我如何从 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);
我需要使用位图图像作为 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);