在 Asynctask 中将视图作为参数发送
Posted
技术标签:
【中文标题】在 Asynctask 中将视图作为参数发送【英文标题】:Send view as a parameter in Asynctask 【发布时间】:2012-10-21 00:17:03 【问题描述】:我正在处理我正在膨胀视图的代码,当用户单击一个视图时,我需要执行解析 URL,然后检查解析是否返回我。问题是我需要在 asynctask 解析中进行才能不出现异常,并且在任务结束之前进行检查。
理想的做法是将视图作为参数发送到 AsyncTask 以将我的所有代码发送到 Asynctask。但不是如何做到这一点
我放代码是为了更容易理解。
vMens.setOnClickListener(new View.OnClickListener()
public void onClick(View vMens)
int readOK=0;
try
new taskMensaje(vMens).execute();
if(mess_gest.equals("1"))
readOK=1;
else
readOK=0;
catch(Exception e)
Utils.showDialog(Calendario.this, "Error", "No se puede gestionar el mensaje");
if (readOK==0)
Mess.state = message.get(vMens.getId()).p1;
Mess.tittle = message.get(vMens.getId()).p2;
else
//message no gest
);
private class taskMensaje extends AsyncTask<String, Void, View>
@Override
protected String doInBackground(String... params)
MensajeriaGestionablePARSER parserMensGest = new MensajeriaGestionablePARSER(urlMensGest);
gestionables = parserMensGest.parse();
mess_gest = gestionables.get(0).p0;
return "";
有解决这个问题的办法吗?
感谢和抱歉我的英语不好
【问题讨论】:
只是小费。首先使用字面量比较字符串是一个好习惯,例如"1".equals(mess_gest)
。它有助于避免 NullPointers。您还可以使用TextUtils.equals("1", mess_gest)
比较字符串。 TextUtils 由 android SDK 提供。
【参考方案1】:
您可以将其作为参数传递给构造函数并将其存储在 AsyncTask 对象中。 将其存储为 WeakReference 并在 onPostExecute 上检查它,就像显示来自官方文档 http://developer.android.com/training/displaying-bitmaps/process-bitmap.html 的图像的最佳实践一样
private class TaskMensaje extends AsyncTask<String, Void, Void>
private WeakReference vRef;
... / your other stuff here
public TaskMensaje (View v)
vRef = new WeakReference(v);
@Override
protected String doInBackground(String... params)
MensajeriaGestionablePARSER parserMensGest = new MensajeriaGestionablePARSER(urlMensGest);
gestionables = parserMensGest.parse();
mess_gest = gestionables.get(0).p0;
return null;
@Override
protected onPostExecute(Void result)
if (vRef != null && bitmap != null)
final ImageView imageView = vRef.get();
if (imageView != null)
// Do whatever you want with your ImageView
...
顺便说一句,请参阅 AsyncTask 参考文档以了解如何在类定义中使用通用参数;-) 在http://developer.android.com/reference/android/os/AsyncTask.html
【讨论】:
我必须投射 vRef:final ImageView imageView = (ImageView)vRef.get();
【参考方案2】:
如果您想将View
作为参数发送给AsyncTask
,简短的回答是不要!
视图来来去去,很有可能在你的AsyncTask
完成时,你的View
已经死去,除了悲伤和沮丧之外,试图访问它不会给你任何东西.
异步处理数据的正确模式是创建一个单独的数据处理类,即Observable
,包括所有AsyncTasks
,花里胡哨。并使您的View
类成为Observer
,它注册接收更新并等待数据处理完毕并通过update()
回调提供给它。
请记住,AsyncTask
是故意从 UI 中分离数据处理,尝试将其绑定回来是完全不合逻辑的。
【讨论】:
【参考方案3】:您可以在异步任务中创建一个构造函数,通过它您可以传递视图并在需要时在异步任务中使用它。
喜欢下面
private class taskMensaje extends AsyncTask<String, Void, String>
private View _view
public taskMensaje(View view)
this._view = view; // this you can use ahead wherever required
@Override
protected String doInBackground(String... params)
MensajeriaGestionablePARSER parserMensGest = new MensajeriaGestionablePARSER(urlMensGest);
gestionables = parserMensGest.parse();
mess_gest = gestionables.get(0).p0;
return "";
【讨论】:
感谢您的回复,怎么办?如何发送我的视图 vMens? 你已经在做 :) new taskMensaje(vMens).execute(); 为什么 View 在你的 asynctask 中使用了第三个参数? 第三个参数是doInBackground方法传递给onPostExecute方法的参数 你的意思是你返回的字符串是一个视图?【参考方案4】:试试这个
vMens.setOnClickListener(new View.OnClickListener()
public void onClick(View vMens)
int readOK=0;
try
new taskMensaje().execute(vMens);
if(mess_gest.equals("1"))
readOK=1;
else
readOK=0;
catch(Exception e)
Utils.showDialog(Calendario.this, "Error", "No se puede gestionar el mensaje");
if (readOK==0)
Mess.state = message.get(vMens.getId()).p1;
Mess.tittle = message.get(vMens.getId()).p2;
else
//message no gest
);
private class taskMensaje extends AsyncTask<View, Void, String>
@Override
protected String doInBackground(View... params)
//Do what ever you want to do with this view
View v=params[0];
return "";
【讨论】:
这几乎是对的,你应该调用“new taskMensaje().execute(vMens);” 这是非常危险的。 AndroidView
对象不是线程安全的,在doInBackground()
中对它们进行任何操作都可能导致间歇性和难以调试的崩溃。如果您需要在解析完成后更新View
,请覆盖onPostExecute()
method并将您的View
相关代码放入其中。
@acj 我知道这不是使用视图的好方法。我刚刚告诉“rgrocha”正在传递的 AsynTask 中的参数序列以上是关于在 Asynctask 中将视图作为参数发送的主要内容,如果未能解决你的问题,请参考以下文章
在 Alamofire Swift 3 中将数组作为参数发送