日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android开发——异步任务中Activity销毁时的问题

發布時間:2025/3/14 Android 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android开发——异步任务中Activity销毁时的问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0.? 前言

在Android開發中經常會發生Activity的銷毀重建,比如用戶長時間接聽一個電話后回到APP。在Android開發——Fragment知識整理(二)我們提到了使用Fragment大量保存Activity銷毀重建數據的方法,但是有一個問題是,在異步任務時旋轉屏幕,如何處理異步任務呢?如果單純的在Activity銷毀之前關閉上一個異步任務,onPostExecute()中的關閉對話框就不會走了,會出現對話框無法關閉的現象;如果不關閉,可能會更新已經不存在的控件,造成錯誤,不僅如此最主要的是Activity的銷毀會造成對話框dismiss空指針異常,因為與當前對話框綁定的FragmentManager已經是null。

因此我們的目標是在異步加載數據時旋轉屏幕,不會對加載任務進行中斷重啟,并且對話框正常顯示。


1.? 繼承Fragment并在其中聲明引用

public class KeepDataFragment extends Fragment {// 保存一個異步的任務private MyAsyncTask data;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setRetainInstance(true);}public void setData(MyAsyncTask data) {this.data = data;}public MyAsyncTask getData() {return data;} }

這里我們創建KeepDataFragment并繼承Fragment,并在其中聲明需要保存的數據對象,這里是保存了一個異步的任務,然后提供gettersetter。最后一定要在onCreate調用setRetainInstance(true)


2.? 異步任務和進度條

public class MyAsyncTask extends AsyncTask<Void, Void, Void> {private MainActivity activity;private boolean isCompleted;private LoadingDialog mLoadingDialog;private List<String> items;public MyAsyncTask(MainActivity activity) {this.activity = activity;}@Overrideprotected void onPreExecute() {mLoadingDialog = new LoadingDialog();mLoadingDialog.show(activity.getFragmentManager(), "LOADING");}@Overrideprotected Void doInBackground(Void... params) {items = loadingData();return null;}private List<String> loadingData() {try {Thread.sleep(5000);} catch (InterruptedException e) {}return new ArrayList<String>(Arrays.asList("東南大學", "信息科學與工程學院", "信息安全學科"));}@Overrideprotected void onPostExecute(Void unused) {isCompleted = true;notifyActivityTaskCompleted();if (mLoadingDialog != null)mLoadingDialog.dismiss();}public List<String> getItems() {return items;}public void setActivity(MainActivity activity) {// 如果上一個Activity銷毀,將與上一個Activity綁定的DialogFragment銷毀if (activity == null) {mLoadingDialog.dismiss();}// 設置為當前的Activitythis.activity = activity;// 開啟一個與當前Activity綁定的等待框if (activity != null && !isCompleted) {mLoadingDialog = new LoadingDialog();mLoadingDialog.show(activity.getFragmentManager(), "LOADING");}// 如果完成,通知Activityif (isCompleted) {notifyActivityTaskCompleted();}}private void notifyActivityTaskCompleted() {if (null != activity) {activity.onTaskCompleted();}} }

這里使用AsyncTask進行異步任務,不熟悉AsyncTask的可以參考Android開發——AsyncTask的使用以及源碼解析任務開始時顯示了一個FragmentDialog對話框,如果不熟悉可以參考Android開發——官方推薦使用DialogFragment替換AlertDialog,這里就不贅述了。任務下載中時,我們模擬了5秒耗時任務并返回了一個字符串List。下載任務結束時讓進度框消失,并為Activity提供回調,因為這里持有了Activity的引用。這里我們也提供了setActivity方法,在Activity被銷毀時在onSaveInstanceState()中設置setActivity(null)取消之前的對話框,同時也防止了內存泄漏;當Activity重建時在onCreate()中設置setActivity(this)傳入新的Activity,從而再次顯示一個加載框,這里需要注意的是Activity的銷毀重建并不影響加載的數據,所有后臺的數據一直繼續在加載。


3.? MainActivity中的實現

public class MainActivity extends ListActivity {private ListAdapter mAdapter;private List<String> mDatas;private KeepDataFragment dataFragment;private MyAsyncTask mMyTask;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);FragmentManager fm = getFragmentManager();dataFragment = (KeepDataFragment) fm.findFragmentByTag("data");if (dataFragment == null) {dataFragment = new KeepDataFragment();fm.beginTransaction().add(dataFragment, "data").commit();}mMyTask = dataFragment.getData();if (mMyTask != null) {//使AsyncTask持有Activity的引用mMyTask.setActivity(this);} else {mMyTask = new MyAsyncTask(this);dataFragment.setData(mMyTask);mMyTask.execute();}}@Overrideprotected void onRestoreInstanceState(Bundle state) {super.onRestoreInstanceState(state);}@Overrideprotected void onSaveInstanceState(Bundle outState) {mMyTask.setActivity(null);super.onSaveInstanceState(outState);}@Overrideprotected void onDestroy() {super.onDestroy();}public void onTaskCompleted() {mDatas = mMyTask.getItems();mAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, mDatas);setListAdapter(mAdapter);} }

onCreate中,如果是第一次進入,則Activity引用傳給AsyncTask、開啟任務mMyTask并把它交給KeepDataFragment來維護,正常情況下AsyncTask正常進行,完成后回調Activity中的onTaskCompleted()。注意要考慮不正常的情況,即加載過程中屏幕的旋轉Activity銷毀時設置setActivity(null)取消之前的對話框,并在Activity重建時KeepDataFragment 實例因為未被銷毀直接通過dataFragment.getData() 取出加載任務mTask并設置setActivity(this)從而再次顯示一個新的加載框,直到任務完成正常進行Activity的回調顯示數據方法。


看一下如下效果,加載數據的5秒鐘內無論如何旋轉屏幕都不會出現問題,這樣就完成了進行異步任務時Activity的銷毀重建不會發生中斷并開啟新的下載任務,而且對話框也會正常顯示。




源碼下載地址點這里

轉載于:https://www.cnblogs.com/qitian1/p/6461454.html

總結

以上是生活随笔為你收集整理的Android开发——异步任务中Activity销毁时的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。