我如何从 AsyncTask class 中获取 doInBackground() 返回的值

How can i get a value returned by doInBackground() from AsyncTask class

我需要使用位图图像作为 Marker.icon。

我有 2 个 AsyncTask class 、 MyTask 和 BitmapTask ,第一个检索一个 JSONArray,其值为 { double,double,string,string = url of my bitmap icon } 和第二个使用 JSONArray 的最后一个字符串(换句话说 url)作为获取位图图标的参数。

尝试以这种方式获取它失败了:

我的任务class

      public class MyTask extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
    //          updateDisplay("Starting task");

        //tasks.add(this);
    }

    @Override
    protected String doInBackground(String... params) {

        String content = HttpManager.getData(params[0]);
        return content;
    }


  @Override
  protected void onPostExecute(String result) {
       double  JsonLat = 0.0  ;
       double  Jsonlong = 0.0 ;
       String  JsonName = "" ;
       String  JsonIconurl = "" ;
       Bitmap  JsonIcon = null;



        try {

            JSONArray cast = new JSONArray(result);
            BitmapTask icontask = new BitmapTask();
            for (int i=0; i<cast.length(); i++) {

                JSONObject Marker = new JSONObject(cast.get(i).toString());
                stringJsonLat = Marker.getString("latitude");
                stringJsonLng = Marker.getString("longitude");
                Jsonlong = Double.parseDouble(stringJsonLng);
                JsonLat = Double.parseDouble(stringJsonLat);
                JsonName = Marker.get("title").toString();
                JsonIconurl = Marker.get("icone").toString();

                 icontask.execute(JsonIconurl);
                 JsonIcon = icontask.doInBackground();

                if (InArea(JsonLat,Jsonlong)) {
                    mMap.addMarker(new MarkerOptions().position(new LatLng(JsonLat,Jsonlong)).title(JsonName).icon(BitmapDescriptorFactory.fromBitmap(JsonIcon)));

                }

            }

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

    }

    @Override
    protected void onProgressUpdate(String... values) {
    //          updateDisplay(values[0]);
    }

}

BitmapTask class

 public class BitmapTask extends AsyncTask<String, Void, Bitmap>{
    @Override
    protected Bitmap doInBackground(String... params) {
        Bitmap bmImg = null;
        try {
            URL url = new URL(params[0]);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bmImg = BitmapFactory.decodeStream(is);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            bmImg = null;
        }

        return bmImg;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        // TODO: do what you need with resulting bitmap - add marker to map
    }
};

运行 你的 MyTask AsyncTask,在 MyTask 的 onPostExecute 中 class 运行 你的 BitmapTask AsyncTask。

MyTask's onPostExecute

@Override
protected void onPostExecute(String result) {
     new BitmapTask().execute(params);   //params if any
}

在您的 BitmapTask class 中,包括以下内容:

public interface BitmapTaskListener{
    public void onResult(Bitmap bmImg);
}

private BitmapTaskListener bitmapListener;

public void setBitmapListener (BitmapTaskListener listener){
    bitmapListener = listener;
}

当然,您不必使用相同的名称。您的 onPostExecute 应该是:

@Override
protected void onPostExecute(Bitmap result) {
    if (bitmapListener!=null)
        bitmapListener.onResult(result);
}

最后,您应该使用 setBitmapListener 来设置侦听器。您将必须实施方法 onResult,您可以在其中使用获得的位图做任何您想做的事情。

编辑:实际上,您是从 MyTask 中调用 BitmapTask。您可以传播侦听器,或者我建议您从 UI 中的第一个任务获取结果并从那里初始化第二个任务。

此外,不要这样做:JsonIcon = icontask.doInBackground();doInBackground 在内部调用,在 onPreExecute 之后。您应该通过 task.execute(params)

开始任务

我建议将所有下载操作集中在一个 AsyncTask 中(下载 JSON 字符串和图标)。

您需要class来包装下载结果:

包装器class:

private class JSONMarkerObject {
    double lat = 0.0;
    double lng = 0.0;
    String name = "";
    String iconURL = "";
    Bitmap iconBitmap = null;
}

辅助函数:

private ArrayList<JSONMarkerObject> parseJSON(String content) {

    ArrayList<JSONMarkerObject> markers = new ArrayList<MainActivity.JSONMarkerObject>();
    try {
        JSONArray array = new JSONArray(content);
        for (int i = 0; i < array.length(); i++) {
            JSONObject Marker = array.getJSONObject(i);
            JSONMarkerObject obj = new JSONMarkerObject();

            obj.lat = Double.parseDouble(Marker.getString("latitude"));
            obj.lng = Double.parseDouble(Marker.getString("longitude"));
            obj.name = Marker.getString("title");
            obj.iconURL = Marker.getString("icone");
            obj.iconBitmap = downloadIcon(obj.iconURL);
            markers.add(obj);
        }

    } catch (NumberFormatException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return markers;

}

private Bitmap downloadIcon(String iconURL) {
    Bitmap bmImg = null;
    try {
        URL url = new URL(iconURL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoInput(true);
        conn.connect();
        InputStream is = conn.getInputStream();
        bmImg = BitmapFactory.decodeStream(is);
    } catch (IOException e) {
        e.printStackTrace();
        bmImg = null;
    }

    return bmImg;
}

下载任务:

public class MyTask extends AsyncTask<String, String, ArrayList<JSONMarkerObject>> {

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected ArrayList<JSONMarkerObject> doInBackground(String... params) {

        String content = HttpManager.getData(params[0]);
        ArrayList<JSONMarkerObject> markers = parseJSON(content);
        return markers;
    }

    @Override
    protected void onPostExecute(ArrayList<JSONMarkerObject> result) {

        try {

            for (int i = 0; i < result.size(); i++) {

                JSONMarkerObject obj = result.get(i);

                if (InArea(obj.lat, obj.lng)) {
                    mMap.addMarker(new MarkerOptions().position(new LatLng(obj.lat, obj.lng)).title(obj.name)
                            .icon(BitmapDescriptorFactory.fromBitmap(obj.iconBitmap)));

                }
            }

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

    @Override
    protected void onProgressUpdate(String... values) {
        // updateDisplay(values[0]);
    }

}

我觉得没必要在一个任务中先下载文字,然后在另一个任务中下载图标,因为图标下载时地图上会出现标记,所以下载没有问题一切尽在其中。

编辑

The simplest way to add an info window is to set the title() and snippet() methods of the corresponding marker.

mMap.addMarker(new MarkerOptions()
.position(new LatLng(obj.lat, obj.lng))
.title(obj.name)
.icon(BitmapDescriptorFactory.fromBitmap(obj.iconBitmap)))
.setTitle(obj.name)
.snippet(obj.name);