android开发分享后台任务,进度对话框,方向更改 – 是否有任何100%的工作解决scheme?

我从后台线程(我使用AsyncTask )从互联网上下载一些数据,并下载时显示进度对话框。 方向更改,活动重新启动,然后我的AsyncTask完成 – 我想closuresprogess对话框,并开始一个新的活动。 但是调用dismissDialog有时会抛出一个exception(可能是因为Activity已经被销毁,新的Activity还没有被启动)。

什么是处理这种问题的最好方法(即使用户改变方向,从后台线程更新UI)? Google有人提供了一些“官方解决scheme”吗?

    步骤1:使你的AsyncTask成为一个static嵌套类,或者一个完全独立的类,而不是一个内部(非静态嵌套)类。

    第二步:让AsyncTask通过一个数据成员保存到Activity ,通过构造函数和setter来设置。

    第3步:创buildAsyncTask ,将当前的Activity给构造函数。

    步骤#4:在onRetainNonConfigurationInstance() ,将AsyncTask从原始的,即将离开的活动中分离出来后返回。

    第5步:在onCreate() ,如果getLastNonConfigurationInstance()不为null ,则将其转换为AsyncTask类,并调用setter将新活动与任务关联。

    步骤#6:不要参考doInBackground()的活动数据成员。

    如果你按照上面的配方,它会一切正常。 onProgressUpdate()onPostExecute()onPostExecute()的开始和后续onCreate()的结束之间挂起。

    这是一个示范项目展示技术。

    另一种方法是抛弃AsyncTask并将您的工作转移到IntentService 。 如果要完成的工作可能很长,并且应该继续进行,而不pipe用户在活动方面做了什么(例如,下载大文件),这是特别有用的。 您可以使用有序的广播Intent来让活动响应正在完成的工作(如果它仍然在前台)或者提出一个Notification让用户知道工作是否已经完成。 这里有一个关于这种模式更多的博客文章 。

    接受的答案是非常有用的,但它没有进展对话框。

    幸运的是,对于读者来说,我已经创build了一个非常全面的AsyncTask实例,并带有一个进度对话框 !

    我已经辛苦了一个星期,find解决这个困境,而不诉诸编辑清单文件。 这个解决scheme的假设是:

    履行

    您将需要将这篇文章底部的两个文件复制到工作区中。 只要确保:


     final static class MyTask extends SuperAsyncTask<Void, Void, Void> { public OpenDatabaseTask(BaseActivity activity) { super(activity, MY_DIALOG_ID); // change your dialog ID here... // and your dialog will be managed automatically! } @Override protected Void doInBackground(Void... params) { // your task code return null; } @Override public boolean onAfterExecute() { // your after execute code } } 

    最后,启动你的新任务:

     mCurrentTask = new MyTask(this); ((MyTask) mCurrentTask).execute(); 

    而已! 我希望这个强大的解决scheme将帮助某人。

    BaseActivity.java (自己组织导入)

     protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Override protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(id, dialog); mDialogMap.put(id, true); } @Override public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } 

    SuperAsyncTask.java

     public abstract class SuperAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Override protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } 

    有人从Google提供了一些“官方解决scheme”?

    是。

    解决scheme更多的是应用程序体系结构build议,而不仅仅是一些代码

    他们提出了3种devise模式 ,允许应用程序与服务器同步工作,而不pipe应用程序状态如何(即使用户完成应用程序,用户更改屏幕,应用程序终止,每隔一个可能的状态一个后台数据操作可能会被中断,这就覆盖了它)

    该build议在Virgil Dobjanschi的Google I / O 2010期间的Android REST客户端应用程序演讲中进行了解释。 这是1小时,但是非常值得一看。

    其基础是将networking操作抽象为独立于应用程序中的任何ActivityService 。 如果您使用的是数据库,一旦使用获取的远程数据更新了本地数据库,使用ContentResolverCursor将为您提供一个开箱即用的Observer模式 ,便于更新UI,而无需任何辅助逻辑。 任何其他操作后的代码将通过传递给Service的callback(我使用ResultReceiver子类来运行)来运行。

    无论如何,我的解释其实很含糊,你应该有把握地观看演讲。

    虽然马克(CommonsWare)的答案确实适用于方向变化,但如果活动被直接销毁,就会失败(就像打电话一样)。

    您可以通过使用Application对象来引用您的ASyncTask来处理方向更改和罕见的被破坏的Activity事件。

    这里有一个很好的解决问题和解决scheme:

    信贷完全由瑞安来找出这一个。

    您应该使用活动处理程序调用所有活动操作。 所以如果你在某个线程中,你应该创build一个Runnable并使用Activitie的Handler进行发布。 否则,您的应用程序有时会崩溃致命的exception。

    谷歌解决了4年后,在Activity onCreate中调用了setRetainInstance(true)的问题。 它将在设备旋转期间保留您的活动实例。 我也有一个较老的Android的简单解决scheme。

    这是我的解决scheme: https : //github.com/Gotchamoh/Android-AsyncTask-ProgressDialog

    基本上这些步骤是:

      以上就是android开发分享后台任务,进度对话框,方向更改 – 是否有任何100%的工作解决scheme?相关内容,想了解更多android开发(异常处理)及android游戏开发关注计算机技术网(www.ctvol.com)!)。

      www.ctvol.com true Article android开发分享后台任务,进度对话框,方向更改 – 是否有任何100%的工作解决scheme?

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/addevelopment/523608.html

      (0)
      上一篇 2020年12月11日 下午10:40
      下一篇 2020年12月11日 下午10:43

      精彩推荐