如何使用 AsyncTask 更新全局变量
Posted
技术标签:
【中文标题】如何使用 AsyncTask 更新全局变量【英文标题】:How to use AsyncTask to update a global variable 【发布时间】:2014-07-20 16:42:35 【问题描述】:我想要做什么:我正在使用自定义“位置”适配器将行放入ListView
。我正在尝试将Bitmap
添加到 ListView 的一行中。此位图来自 URL。所以,我有一个全局变量public static Bitmap bitmap
并想使用 AsyncTask 更新这个变量。这是我的代码:
try
String s = "";
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++)
final JSONObject json = jArray.getJSONObject(i);
runOnUiThread(new Runnable()
@Override
public void run()
try
//here I am calling my new task and giving it the ID to find the image
BitmapWorkerTask myTask = new BitmapWorkerTask(json.getInt("ID"));
myTask.execute();
adapter.add(new Location(bitmap, json
.getString("PlaceTitle"), json
.getString("PlaceDetails"), json
.getString("PlaceDistance"), json
.getString("PlaceUpdatedTime")));
bitmap = null;
catch (JSONException e)
// TODO Auto-generated catch block
e.printStackTrace();
);
catch (Exception e)
// TODO: handle exception
Log.e("log_tag", "Error Parsing Data " + e.toString());
这是我的异步任务
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap>
private int photoID = 0;
public BitmapWorkerTask(int photoID)
// Use a WeakReference to ensure the ImageView can be garbage collected
this.photoID = photoID;
// Decode image in background.
@Override
protected Bitmap doInBackground(Integer... params)
String initialURL = "http://afs.spotcontent.com/img/Places/Icons/";
final String updatedURL = initialURL + photoID + ".jpg";
Bitmap bitmap2 = null;
try
bitmap2 = BitmapFactory.decodeStream((InputStream) new URL(
updatedURL).getContent());
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
return bitmap2;
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap2)
bitmap = bitmap2;
因此,对于每次迭代,我都会为 AsyncTask 提供一个用于查找图像的 ID,然后(我希望)应该更新传递给适配器的全局位图。当我运行我的应用程序时,每个列表的图片都是空的。关于我做错了什么有什么想法吗?
【问题讨论】:
onPostExecute
是否为bitmap2
返回正确的位图?另外,onPostExecute
中的 bitmap
变量不应该像 ClassName.bitmap 那样静态访问吗?
我假设它正在为 bitmap2 发回正确的位图。 doInBackground 方法检索 bitmap2,然后 onPostExecute 设置全局 bitmap = bitmap2。对吗?
我知道doInBackground中位图的检索是成功的,因为我已经在AsyncTask之外尝试过了
好吧,假设我们不知道。在 doInBackground 上进行调试或将System.out.println()
添加到 doInBackground 中的异常中,以查看那里是否发生了任何事情。然后继续前进。
正在检索位图。我设置了一个 imageView = 位图,它起作用了。出于某种原因,它没有更新全局位图变量
【参考方案1】:
考虑以下可能的命令执行顺序(记住任务在后台运行,因此顺序是不确定的):
-
myTask.execute()
BitmapWorkerTask.doInBackground()
adapter.Add(new Location(bitmap, .......
BitmapWorkerTask.onPostExecute()
当您在步骤 3 中创建 Location() 对象时,传递的“位图”对象是全局对象指针。它的值还不是有效的,因为 onPostExecute() 还没有被调用。所以 Location 对象是用非位图对象创建的。在第 4 步,当最终检索到位图时,全局对象指针的值已更改(正确),但这不会影响已在第 2 步中传递给 Location 的(空)位图对象......这就是为什么你在您的视图中看不到位图。
您可以做的是向 BitmapWorkerTask 构造函数传递一个附加参数:您可以传递 Location 对象(或底层位图)。然后,您可以从 onPostExecute() 使用检索到的位图更新该位置/位图对象。这里不需要全局变量。
【讨论】:
这行得通。非常感谢,我不知道为什么这个解决方案从我身边溜走了。 +1!以上是关于如何使用 AsyncTask 更新全局变量的主要内容,如果未能解决你的问题,请参考以下文章