我知道有很多东西AsyncTask,我已经探索了很长一段时间,但仍然没有发现灵魂。我必须以串行方式将图像上传到FTP服务器上。我知道在API 11以及之后,默认情况下AsyncTask会顺序执行。但是,不是完全顺序的...到目前为止,我的观察是:只有DoInBackgorund()方法是按顺序执行的,因此,如果您有N个异步任务被调用执行,则它们的OnPreExecute()被独立于其他正在执行的Asynctask的执行而调用。我想要的是完整的顺序执行,如下所示:
异步任务1:
OnPreExecute();
DoInBackgorund();
OnPostExecute();
其次是 :
异步任务2:
OnPreExecute();
DoInBackgorund();
OnPostExecute();
其次是 :
异步任务2:
OnPreExecute();
DoInBackgorund();
OnPostExecute();
... 等等。
请向我提供一些想法,调整或概念,以实现异步线程的完整顺序执行。虚拟代码将不胜感激。提前致谢。
编辑:图像上传机制非常好,正在上传图像。我正在创建uploadTask的实例(我的AsyncTask用于上传图像)并循环执行它们。唯一的问题是;我必须在每个线程的OnPreExecute()中更新UI(以在TextView中显示要上传的图像数)。这是我的问题,因为OnPreExecute()没有顺序执行。
使用publishProgress和onProgressUpdate替换您在onPreExecute中所做的操作:developer.android.com/reference/android/os/
最简单的选择:只有一个AsyncTask,您可以在单个doInBackground()中处理所有工作,并根据需要使用publishProgress()和onProgressUpdate()发布每次下载的结果。 我不知道您为什么认为拥有N个非并行AsyncTask实例是一个好主意。
或者:根本不使用AsyncTask。 使用您自己的ThreadPoolExecutor,因此您可以完全控制作业的特征。 使用事件总线(greenrobot的EventBus,Otto,LocalBroadcastManager等)在UI线程上发布结果。
或者:从第一个AsyncTask的onPostExecute()开始启动链中的下一个AsyncTask。
我认为并行执行不是一个好主意的原因是:我将图像上传到具有共享主机的FTP服务器和FTP服务器上,我们都知道线程的并行执行会减慢单个线程的处理速度,并且还会导致复杂的线程同步。
它不会并行执行。在同一线程中,它将在doInBackground中是串行的。
我根本不熟悉1st 2提出的解决方案:(
您是说我应该在单线程中上传10张图片吗?我不认为你的意思是
@d ?? lhm&d:"您是说我应该在单线程中上传10张图片吗?" -当然。那是顺序执行AsyncTask列表的最终效果。请记住:您是说您想要顺序行为的人。通常,对于网络I / O,并行线程很好(在一定程度上),因为这些线程通常会阻塞网络I / O本身,因此不会持续消耗CPU。但是,如果您要顺序上传,那很好,但是您也可以只使用一个线程。
正如您所说的那样,第一个建议将完全按顺序进行。如果您只有一个AsyncTask,则其doInBackground方法一次将上传1张图片-为什么您认为每个图片都需要一个新的asynctask?
@CommonsWare,好的,如果我在单个DoInBackground()执行中上传N个图像,我不认为建议在任何地方长时间运行asynctasks,而且,在所有图像上传完成之前,我将无法更新UI
@SamDozor我对publishProgress()和onProgressUpdate()一无所知。所以我最好先研究他们。
@d ?? lhm&d:"我不认为建议在任何地方运行长时间的异步任务" –就个人而言,我会使用IntentService。但是,长时间运行的单个AsyncTask的风险没有连续N个连续的连续运行的AsyncTasks更大。"在完成所有图像的上传之前,我将无法更新UI"-使用publishProgress()和onProgressUpdate(),如我的回答所述。参见:github.com/commonsguy/cw-omnibus/tree/master/Threads/AsyncTask
到目前为止,非常感谢您的指导,即时通讯开始处理您的建议。完成后将接受答案。再次感谢。
@CommonsWare虽然我的问题现在已经解决,并且一切都很好,但是请给我您的意见;我应该上传带有循环INSIDE DoInBackground()的所有图像,还是应该通过每次上传单个图像调用task.execute()来上传所有图像?
@d ?? lhm&d:我会使用IntentService。缺少这一点,我将在DoInBackground()中使用单个AsyncTask和循环。
在OnPostExecute()上实现接口回调
eg.
//activity
MyActivity extends Activity implements MyInterface
{
@Override
public void Task1Complete()
{
new StartTask2(getActivity, MyActivity.this).execute();
}
//Interface
public interface MyInterface
{
void Task1Complete()
}
//AsyncTask1
public class task1 extends AsyncTask
{
Context ctx;
MyInterface myInterface;
public task1(Context _ctx, MyInterface _myInterface)
{
this.ctx = _ctx;
this.myInterface = _myInterface;
}
doinbackground{}
onpostexecute()
{
myInterface.Task1Complete();
}
感谢您的回答,但以上解决了我的问题:)