Android Google Maps v2从JSON数组php mySQL添加地图标记

时间:2021-06-04 13:38:54

I'm trying to create an Android App that draw markers on Google Maps v2 from my mySQL database, but it doesn´t work.

我正在尝试创建一个从我的mySQL数据库在Google Maps v2上绘制标记的Android应用程序,但它不起作用。

Mapactivity.java

    public class MapsActivity extends FragmentActivity  {
    // Creating JSON Parser object
    JSONParser jParser = new JSONParser();
    // url to get all products list
    private static String url_all_products = "http://127.0.0.1/get_marker.php";
    // JSON Node names
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_Coordinates = "products";
    private static final String TAG_PID = "pid";
    private static final String TAG_X = "x_coordinate";
    private static final String TAG_Y = "y_coordinate";
    // products JSONArray
    JSONArray products = null;
    private GoogleMap mMap; // Might be null if Google Play services APK is not available.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        setUpMapIfNeeded();
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.

            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {



                // Add marker info window click listener
              //  mMap.setOnInfoWindowClickListener(this);
                //Zooming Buttons
                UiSettings mapSettings;
                mapSettings = mMap.getUiSettings();
                mapSettings.setZoomControlsEnabled(true);
                //Zooming Buttons


                GetMarker();
            }
        }
    }
    private void GetMarker()
    {
        mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
        mMap.setMyLocationEnabled(true);
        double xi = 49.999065;
        double yi = 8.273978;

        LatLng MUSEUM = new LatLng(xi , yi);
        Marker museum = mMap.addMarker(new MarkerOptions()
                .position(MUSEUM)
                .title("Mainzer Dom")
                .snippet("Der Mainzer Dom"));


        new Thread(new Runnable() {
            public void run() {
                retrieveAndAddCities();
            }
        }).start();

    }

    private void retrieveAndAddCities()  {

        List params = new ArrayList();
        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);

        // Check your log cat for JSON reponse
        Log.d("All Products: ", json.toString());

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {
                // products found
                // Getting Array of Products
                products = json.getJSONArray(TAG_Coordinates);

                // looping through All Products
                for (int i = 0; i < products.length(); i++) {
                    JSONObject c = products.getJSONObject(i);

                    // Storing each json item in variable
                    int id = c.getInt(TAG_PID);
                    double x_coordinate = c.getDouble(TAG_X);
                    double y_coordinate = c.getDouble(TAG_Y);
                    mMap.addMarker(new MarkerOptions()
                            .position(new LatLng(x_coordinate,y_coordinate )));
                }

            } else {


            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

}

And my php code: get_marker.php

我的PHP代码:get_marker.php

    <?php

/*
 * Following code will list all the products
 */


$response = array();


require_once __DIR__ . '/db_connect.php';


$db = new DB_CONNECT();


$result = mysql_query("SELECT *FROM products") or die(mysql_error());


if (mysql_num_rows($result) > 0) {

    $response["products"] = array();

    while ($row = mysql_fetch_array($result)) {

        $product = array();
        $product["pid"] = $row["pid"];
        $product["x_coordinate"] = $row["x_coordinate"];
        $product["y_coordinate"] = $row["y_coordinate"];
        $product["created_at"] = $row["created_at"];
        $product["updated_at"] = $row["updated_at"];


        array_push($response["products"], $product);
    }

    $response["success"] = 1;

    // echoing JSON response
    echo json_encode($response);
} else {

    $response["success"] = 0;
    $response["message"] = "No products found";


    echo json_encode($response);
}
?>

and this is the JsonParser

这是JsonParser

public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    // constructor
    public JSONParser() {

    }

    // function get json from url
    // by making HTTP POST or GET mehtod
    public JSONObject makeHttpRequest(String url, String method,
                                      List<NameValuePair> params) {

        // Making HTTP request
        try {

            // check for request method
            if(method == "POST"){
                // request method is POST
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);
                httpPost.setEntity(new UrlEncodedFormEntity(params));

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();

            }else if(method == "GET"){
                // request method is GET
                DefaultHttpClient httpClient = new DefaultHttpClient();
                String paramString = URLEncodedUtils.format(params, "utf-8");
                url += "?" + paramString;
                HttpGet httpGet = new HttpGet(url);

                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;

    }
}

If i try to start the retrieveAndAddCities();

如果我尝试启动retrieveAndAddCities();

new Thread(new Runnable() {
            public void run() {
                retrieveAndAddCities();
            }
        }).start();

my App will crash.

我的应用程序将崩溃。

I hope someone can help me. thanks a lot

我希望有一个人可以帮助我。非常感谢

edit: Logcat:

04-06 01:50:04.268    5153-5168/flo.myapplication D/OpenGLRenderer﹕ Render dirty regions requested: true
04-06 01:50:04.271    5153-5153/flo.myapplication D/﹕ HostConnection::get() New Host Connection established 0xae0d8560, tid 5153
04-06 01:50:04.304    5153-5153/flo.myapplication D/Atlas﹕ Validating map...
04-06 01:50:04.364    5153-5168/flo.myapplication D/﹕ HostConnection::get() New Host Connection established 0xae0d8ae0, tid 5168
04-06 01:50:04.373    5153-5168/flo.myapplication I/OpenGLRenderer﹕ Initialized EGL, version 1.4
04-06 01:50:04.446    5153-5168/flo.myapplication D/OpenGLRenderer﹕ Enabling debug mode 0
04-06 01:50:04.465    5153-5168/flo.myapplication W/EGL_emulation﹕ eglSurfaceAttrib not implemented
04-06 01:50:04.465    5153-5168/flo.myapplication W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa605e2c0, error=EGL_SUCCESS
04-06 01:50:11.068    5153-5153/flo.myapplication I/zzx﹕ Making Creator dynamically
04-06 01:50:11.071    5153-5153/flo.myapplication W/ResourcesManager﹕ Asset path '/system/framework/com.android.media.remotedisplay.jar' does not exist or contains no resources.
04-06 01:50:11.071    5153-5153/flo.myapplication W/ResourcesManager﹕ Asset path '/system/framework/com.android.location.provider.jar' does not exist or contains no resources.
04-06 01:50:11.088    5153-5153/flo.myapplication I/Google Maps Android API﹕ Google Play services client version: 7095000
04-06 01:50:11.092    5153-5153/flo.myapplication I/Google Maps Android API﹕ Google Play services package version: 7097470
04-06 01:50:11.205    5153-5165/flo.myapplication I/art﹕ Background partial concurrent mark sweep GC freed 11075(592KB) AllocSpace objects, 0(0B) LOS objects, 38% free, 6MB/10MB, paused 5.446ms total 25.641ms
04-06 01:50:11.363    5153-5165/flo.myapplication I/art﹕ Background sticky concurrent mark sweep GC freed 49928(2039KB) AllocSpace objects, 3(561KB) LOS objects, 0% free, 11MB/11MB, paused 2.593ms total 119.732ms
04-06 01:50:11.423    5153-5165/flo.myapplication I/art﹕ Background partial concurrent mark sweep GC freed 12702(547KB) AllocSpace objects, 2(1015KB) LOS objects, 28% free, 10MB/14MB, paused 5.173ms total 52.148ms
04-06 01:50:11.551    5153-5153/flo.myapplication I/Choreographer﹕ Skipped 31 frames!  The application may be doing too much work on its main thread.
04-06 01:50:11.608    5153-5168/flo.myapplication W/EGL_emulation﹕ eglSurfaceAttrib not implemented
04-06 01:50:11.608    5153-5168/flo.myapplication W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa602e720, error=EGL_SUCCESS
04-06 01:50:11.648    5153-5185/flo.myapplication D/﹕ HostConnection::get() New Host Connection established 0xa5491d90, tid 5185
04-06 01:50:11.657    5153-5186/flo.myapplication D/All Products:﹕ {"products":[{"pid":"1","x_coordinate":"50","y_coordinate":"8","created_at":"2015-04-06 01:13:22","updated_at":"0000-00-00 00:00:00"}],"success":1}
04-06 01:50:11.657    5153-5186/flo.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-378
    Process: flo.myapplication, PID: 5153
    java.lang.IllegalStateException: Not on the main thread
            at com.google.l.a.cd.b(Unknown Source)
            at com.google.maps.api.android.lib6.c.ca.a(Unknown Source)
            at com.google.maps.api.android.lib6.c.el.a(Unknown Source)
            at com.google.android.gms.maps.internal.l.onTransact(SourceFile:167)
            at android.os.Binder.transact(Binder.java:380)
            at com.google.android.gms.maps.internal.IGoogleMapDelegate$zza$zza.addMarker(Unknown Source)
            at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source)
            at flo.myapplication.MapsActivity.retrieveAndAddCities(MapsActivity.java:201)
            at flo.myapplication.MapsActivity.access$000(MapsActivity.java:98)
            at flo.myapplication.MapsActivity$1.run(MapsActivity.java:168)
            at java.lang.Thread.run(Thread.java:818)

okay, i modified the code with AsyncTask now, but i get errors too

好吧,我现在用AsyncTask修改了代码,但我也得到了错误

package flo.myapplication;

import android.os.StrictMode;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Dialog;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MapsActivity extends FragmentActivity  {
    // Creating JSON Parser object
    JSONParser jParser = new JSONParser();
    // url to get all products list
    private static String url_all_products = "http://88.198.46.8/get_marker.php";
    // JSON Node names
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_Coordinates = "products";
    private static final String TAG_PID = "pid";
    private static final String TAG_X = "x_coordinate";
    private static final String TAG_Y = "y_coordinate";
    // products JSONArray
    JSONArray products = null;
    private GoogleMap mMap; // Might be null if Google Play services APK is not available.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        setUpMapIfNeeded();
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.

            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {



                // Add marker info window click listener
              //  mMap.setOnInfoWindowClickListener(this);
                //Zooming Buttons
                UiSettings mapSettings;
                mapSettings = mMap.getUiSettings();
                mapSettings.setZoomControlsEnabled(true);
                //Zooming Buttons


                GetMarker();
            }
        }
    }
    private void GetMarker()
    {
        mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
        mMap.setMyLocationEnabled(true);
        double xi = 49.999065;
        double yi = 8.273978;

        LatLng MUSEUM = new LatLng(xi , yi);
        Marker museum = mMap.addMarker(new MarkerOptions()
                .position(MUSEUM)
                .title("Mainzer Dom")
                .snippet("Der Mainzer Dom"));


        // Loading products in Background Thread
        new retrieveAndAddCities().execute();





    }

    class retrieveAndAddCities extends AsyncTask<String, String, String> {
        protected String doInBackground(String... args) {
            List params = new ArrayList();
            // getting JSON string from URL
            JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);

            // Check your log cat for JSON reponse
            Log.d("All Products: ", json.toString());

            try {
                // Checking for SUCCESS TAG
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    // products found
                    // Getting Array of Products
                    products = json.getJSONArray(TAG_Coordinates);

                    // looping through All Products
                    for (int i = 0; i < products.length(); i++) {
                        JSONObject c = products.getJSONObject(i);

                        // Storing each json item in variable
                        int id = c.getInt(TAG_PID);
                        double x_coordinate = c.getDouble(TAG_X);
                        double y_coordinate = c.getDouble(TAG_Y);
                        mMap.addMarker(new MarkerOptions()
                                .position(new LatLng(x_coordinate,y_coordinate )));
                    }

                } else {


                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

    }



}

and Logcat File:

和Logcat文件:

04-06 02:29:30.055    5324-5339/flo.myapplication D/OpenGLRenderer﹕ Render dirty regions requested: true
04-06 02:29:30.076    5324-5324/flo.myapplication D/﹕ HostConnection::get() New Host Connection established 0xae0d5550, tid 5324
04-06 02:29:30.129    5324-5324/flo.myapplication D/Atlas﹕ Validating map...
04-06 02:29:30.274    5324-5339/flo.myapplication D/﹕ HostConnection::get() New Host Connection established 0xae0d59a0, tid 5339
04-06 02:29:30.397    5324-5339/flo.myapplication I/OpenGLRenderer﹕ Initialized EGL, version 1.4
04-06 02:29:30.574    5324-5339/flo.myapplication D/OpenGLRenderer﹕ Enabling debug mode 0
04-06 02:29:30.693    5324-5339/flo.myapplication W/EGL_emulation﹕ eglSurfaceAttrib not implemented
04-06 02:29:30.693    5324-5339/flo.myapplication W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa604a400, error=EGL_SUCCESS
04-06 02:29:30.788    5324-5324/flo.myapplication I/Choreographer﹕ Skipped 37 frames!  The application may be doing too much work on its main thread.
04-06 02:29:37.319    5324-5324/flo.myapplication I/zzx﹕ Making Creator dynamically
04-06 02:29:37.321    5324-5324/flo.myapplication W/ResourcesManager﹕ Asset path '/system/framework/com.android.media.remotedisplay.jar' does not exist or contains no resources.
04-06 02:29:37.321    5324-5324/flo.myapplication W/ResourcesManager﹕ Asset path '/system/framework/com.android.location.provider.jar' does not exist or contains no resources.
04-06 02:29:37.336    5324-5324/flo.myapplication I/Google Maps Android API﹕ Google Play services client version: 7095000
04-06 02:29:37.361    5324-5324/flo.myapplication I/Google Maps Android API﹕ Google Play services package version: 7097470
04-06 02:29:37.396    5324-5336/flo.myapplication I/art﹕ Background sticky concurrent mark sweep GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 1% free, 2MB/2MB, paused 5.461ms total 9.101ms
04-06 02:29:37.582    5324-5336/flo.myapplication I/art﹕ Background partial concurrent mark sweep GC freed 45498(2MB) AllocSpace objects, 11(2MB) LOS objects, 29% free, 9MB/13MB, paused 999us total 105.746ms
04-06 02:29:37.835    5324-5324/flo.myapplication I/Choreographer﹕ Skipped 32 frames!  The application may be doing too much work on its main thread.
04-06 02:29:37.924    5324-5339/flo.myapplication W/EGL_emulation﹕ eglSurfaceAttrib not implemented
04-06 02:29:37.924    5324-5339/flo.myapplication W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa6078180, error=EGL_SUCCESS
04-06 02:29:37.977    5324-5358/flo.myapplication D/All Products:﹕ {"products":[{"pid":"1","x_coordinate":"50","y_coordinate":"8","created_at":"2015-04-06 01:13:22","updated_at":"0000-00-00 00:00:00"}],"success":1}
04-06 02:29:37.978    5324-5358/flo.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    Process: flo.myapplication, PID: 5324
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:300)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
     Caused by: java.lang.IllegalStateException: Not on the main thread
            at com.google.l.a.cd.b(Unknown Source)
            at com.google.maps.api.android.lib6.c.ca.a(Unknown Source)
            at com.google.maps.api.android.lib6.c.el.a(Unknown Source)
            at com.google.android.gms.maps.internal.l.onTransact(SourceFile:167)
            at android.os.Binder.transact(Binder.java:380)
            at com.google.android.gms.maps.internal.IGoogleMapDelegate$zza$zza.addMarker(Unknown Source)
            at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source)
            at flo.myapplication.MapsActivity$retrieveAndAddCities.doInBackground(MapsActivity.java:200)
            at flo.myapplication.MapsActivity$retrieveAndAddCities.doInBackground(MapsActivity.java:174)
            at android.os.AsyncTask$2.call(AsyncTask.java:288)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
04-06 02:29:38.024    5324-5357/flo.myapplication D/﹕ HostConnection::get() New Host Connection established 0x9fbe30a0, tid 5357
04-06 02:29:38.833    5324-5336/flo.myapplication I/art﹕ Background partial concurrent mark sweep GC freed 10277(451KB) AllocSpace objects, 32(1505KB) LOS objects, 23% free, 13MB/17MB, paused 795us total 118.120ms

2 个解决方案

#1


0  

Your app is crashing because you are trying to update the UI off of the main thread. Your JSON request is successful but the app crashes when your code hits mMap.addMarker().

您的应用程序崩溃了,因为您正在尝试更新主线程的UI。您的JSON请求成功,但当您的代码遇到mMap.addMarker()时应用程序崩溃。

http://developer.android.com/guide/components/processes-and-threads.html

Using AsyncTask is a good idea but you will have to only do the JSON request in doInBackground() because doInBackground does not run on the main thread and your app will crash the same way it currently is. If you do use an AsyncTask just take a look at the documentation. Google has a pretty good example.

使用AsyncTask是一个好主意,但是您必须只在doInBackground()中执行JSON请求,因为doInBackground不会在主线程上运行,并且您的应用程序将以与当前相同的方式崩溃。如果您确实使用AsyncTask,请查看文档。谷歌有一个很好的例子。

http://developer.android.com/reference/android/os/AsyncTask.html

I modified your retrieveAndAddCities class to work correctly. doInBackground now returns a JSONArray of products. When doInBackground is complete the JSONArray of products is passed as a parameter in onPostExecute. onPostExecute runs on the main thread. It now contains the for loop where you were looping through the products and adding map markers.

我修改了retrieveAndAddCities类以使其正常工作。 doInBackground现在返回产品的JSONArray。当doInBackground完成时,产品的JSONArray将作为onPostExecute中的参数传递。 onPostExecute在主线程上运行。它现在包含for循环,您循环遍历产品并添加地图标记。

class retrieveAndAddCities extends AsyncTask< Void, Void, JSONArray > {
    protected JSONArray doInBackground(Void... args) {
        List params = new ArrayList();
        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);

        // Check your log cat for JSON reponse
        Log.d("All Products: ", json.toString());

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {
                // products found
                // Getting Array of Products
                return json.getJSONArray(TAG_Coordinates);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute(JSONArray products) {
        if (products != null) {
            for (int i = 0; i < products.length(); i++) {
                JSONObject c = null;
                try {
                    c = products.getJSONObject(i);
                    // Storing each json item in variable
                    int id = c.getInt(TAG_PID);
                    double x_coordinate = c.getDouble(TAG_X);
                    double y_coordinate = c.getDouble(TAG_Y);
                    mMap.addMarker(new MarkerOptions()
                            .position(new LatLng(x_coordinate, y_coordinate)));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        } else {
            //Handle case of no products or failure
        }
    }
}

#2


0  

Ok then you can use async task like this, there may be some syntax errors in my code, but you can do it like this.

那么你可以像这样使用异步任务,我的代码中可能会有一些语法错误,但你可以这样做。

public class myclass extends  Asynctask<Void,Void,Void>{
@Override
 public void doInBackground(){
   retrieveAndAddCities();    }
}

#1


0  

Your app is crashing because you are trying to update the UI off of the main thread. Your JSON request is successful but the app crashes when your code hits mMap.addMarker().

您的应用程序崩溃了,因为您正在尝试更新主线程的UI。您的JSON请求成功,但当您的代码遇到mMap.addMarker()时应用程序崩溃。

http://developer.android.com/guide/components/processes-and-threads.html

Using AsyncTask is a good idea but you will have to only do the JSON request in doInBackground() because doInBackground does not run on the main thread and your app will crash the same way it currently is. If you do use an AsyncTask just take a look at the documentation. Google has a pretty good example.

使用AsyncTask是一个好主意,但是您必须只在doInBackground()中执行JSON请求,因为doInBackground不会在主线程上运行,并且您的应用程序将以与当前相同的方式崩溃。如果您确实使用AsyncTask,请查看文档。谷歌有一个很好的例子。

http://developer.android.com/reference/android/os/AsyncTask.html

I modified your retrieveAndAddCities class to work correctly. doInBackground now returns a JSONArray of products. When doInBackground is complete the JSONArray of products is passed as a parameter in onPostExecute. onPostExecute runs on the main thread. It now contains the for loop where you were looping through the products and adding map markers.

我修改了retrieveAndAddCities类以使其正常工作。 doInBackground现在返回产品的JSONArray。当doInBackground完成时,产品的JSONArray将作为onPostExecute中的参数传递。 onPostExecute在主线程上运行。它现在包含for循环,您循环遍历产品并添加地图标记。

class retrieveAndAddCities extends AsyncTask< Void, Void, JSONArray > {
    protected JSONArray doInBackground(Void... args) {
        List params = new ArrayList();
        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);

        // Check your log cat for JSON reponse
        Log.d("All Products: ", json.toString());

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {
                // products found
                // Getting Array of Products
                return json.getJSONArray(TAG_Coordinates);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute(JSONArray products) {
        if (products != null) {
            for (int i = 0; i < products.length(); i++) {
                JSONObject c = null;
                try {
                    c = products.getJSONObject(i);
                    // Storing each json item in variable
                    int id = c.getInt(TAG_PID);
                    double x_coordinate = c.getDouble(TAG_X);
                    double y_coordinate = c.getDouble(TAG_Y);
                    mMap.addMarker(new MarkerOptions()
                            .position(new LatLng(x_coordinate, y_coordinate)));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        } else {
            //Handle case of no products or failure
        }
    }
}

#2


0  

Ok then you can use async task like this, there may be some syntax errors in my code, but you can do it like this.

那么你可以像这样使用异步任务,我的代码中可能会有一些语法错误,但你可以这样做。

public class myclass extends  Asynctask<Void,Void,Void>{
@Override
 public void doInBackground(){
   retrieveAndAddCities();    }
}