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

歡迎訪問 生活随笔!

生活随笔

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

Android

Android Loader 异步加载详解二:探寻Loader内部机制

發(fā)布時間:2024/9/30 Android 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Loader 异步加载详解二:探寻Loader内部机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Android Loader 異步加載詳解二:探尋Loader內(nèi)部機制

轉(zhuǎn)載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/70259914
本文出自【趙彥軍的博客】

Android Loader 異步加載詳解一:基礎概念
Android Loader 異步加載詳解二:探尋Loader內(nèi)部機制

在上一篇文章中,講解了 Loader 的基本概念。這一篇將會用實戰(zhàn)的方式來探尋 Android Loader的內(nèi)部機制。我們準備做一個 讀取手機短信的例子。廢話不多說,直接上效果圖:

所有的代碼都在:https://github.com/zyj1609wz/Loader

實例源碼

  • 首先 SmsActivity 的源碼
package com.app.loader.sms;import android.app.LoaderManager; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import com.app.loader.R;public class SmsActivity extends AppCompatActivity {private int loaderId = 0 ;private ListView lv;private SimpleCursorAdapter adapter;private LoaderManager.LoaderCallbacks loaderCallbacks ;private EditText editText ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_sms );Log.e( "loader", "activity onCreate: ");lv = (ListView) findViewById( R.id.listview );adapter = new SimpleCursorAdapter(this,R.layout.sms_listview_item ,null,new String[]{"address","body"},new int[]{R.id.address, R.id.body},SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);lv.setAdapter(adapter);loaderCallbacks = new MyCallback() ;//初始化,并且創(chuàng)建Loader 實例,并且開始執(zhí)行getLoaderManager().initLoader( loaderId , null, loaderCallbacks );editText = (EditText) findViewById( R.id.editText );findViewById( R.id.start).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//開始查詢String tag = editText.getText().toString() ;Bundle bundle = new Bundle();bundle.putString("key", tag );getLoaderManager().restartLoader( loaderId , bundle, loaderCallbacks );}});findViewById( R.id.init).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//初始化,并且創(chuàng)建Loader 實例,并且開始執(zhí)行getLoaderManager().initLoader( loaderId , null, loaderCallbacks );}});}class MyCallback implements LoaderManager.LoaderCallbacks<Cursor> {@Overridepublic Loader onCreateLoader(int id, Bundle args) {SmsLoader loader = new SmsLoader( SmsActivity.this , args);Log.e( "loader", "onCreateLoader: ");return loader ;}@Overridepublic void onLoadFinished(Loader<Cursor> loader, Cursor data) {Log.e( "loader", "onLoadFinished: ");adapter.changeCursor( data );}@Overridepublic void onLoaderReset(Loader loader) {Log.e( "loader", "onLoaderReset: ");//當 Activity OnDestory() , 系統(tǒng)會回調(diào)這個方法adapter.swapCursor(null);}}@Overrideprotected void onResume() {Log.e( "loader", "activity onResume: ");super.onResume();}@Overrideprotected void onPause() {Log.e( "loader", "activity onPause: ");super.onPause();}@Overrideprotected void onDestroy() {Log.e( "loader", "activity onDestroy: ");super.onDestroy();} }
  • activity_sms 布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.app.loader.MainActivity"><EditText android:id="@+id/editText"android:layout_width="match_parent"android:layout_height="50dp"android:hint="請你輸入過濾關鍵詞"/><Button android:id="@+id/start"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="開始查詢"/><Button android:id="@+id/init"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="開始執(zhí)行 init方法"/><ListView android:id="@+id/listview"android:layout_width="match_parent"android:layout_height="match_parent"></ListView></LinearLayout>
  • SmsLoader 類繼承 AsyncTaskLoader
package com.app.loader.sms;import android.content.AsyncTaskLoader; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log;/*** Created by ${zhaoyanjun} on 2017/4/19.*/public class SmsLoader extends AsyncTaskLoader<Cursor> {private Bundle bundle;private Uri uri = Uri.parse("content://sms");private String []colums = {"_id","address","body"};public SmsLoader(Context context , Bundle bundle ) {super(context);this.bundle = bundle;}@Overridepublic Cursor loadInBackground() {String selection = null;String[] selectionArgs = null;if (bundle!=null) {selection = "body like ? ";selectionArgs = new String[]{"%"+bundle.getString("key")+"%"};}Cursor cursor = getContext().getContentResolver().query(uri, colums, selection , selectionArgs, null);Log.e( "loader", "loadInBackground: ");return cursor;}@Overrideprotected void onStartLoading() {super.onStartLoading();forceLoad();Log.e( "loader", "onStartLoading: ");//這里一定要執(zhí)行 forceLoad(); 否則 Loader 不會正常工作// onStartLoading() --> forceLoad --> 調(diào)用 AsyncTaskLoader 里面的 forceLoad()// --> 開始創(chuàng)建 AsyncTask 對象實例,并且運行 AsyncTask 的 doInBackground --> SmsLoader 類中 loadInBackground()// --> 開始把結果 回調(diào)給主線程 AsyncTask onPostExecute() --> AsyncTaskLoader dispatchOnLoadComplete()// -- AsyncTaskLoader deliverResult() 把最后的結果回調(diào)給 LoaderManager.LoaderCallbacks} }

測試

  • 第一次 Activity 啟動 Log 日志分析 :
com.app.loader E/loader: activity onCreate: com.app.loader E/loader: onCreateLoader: com.app.loader E/loader: onStartLoading: com.app.loader E/loader: loadInBackground: com.app.loader E/loader: onLoadFinished:

可以看到 第一次調(diào)用 initLoader() 方法后

//初始化,并且創(chuàng)建Loader 實例,并且開始執(zhí)行getLoaderManager().initLoader( loaderId , null, loaderCallbacks );

首先 調(diào)用 LoaderCallbacks 中的 onCreateLoader 來創(chuàng)建一個 Loader 對象,然后調(diào)用 SmsLoader 中的 onStartLoading方法。然后調(diào)用 SmsLoader 中的 loadInBackground 開始執(zhí)行 異步任務。最后在 LoaderCallbacks 中 onLoadFinished 方法中回調(diào)。

  • 點擊 “開始執(zhí)行 Init 方法” 按鈕,Log 分析
    點擊 “開始執(zhí)行 Init 方法”按鈕后,開始執(zhí)行
getLoaderManager().initLoader( loaderId , null, loaderCallbacks );

Log 日志為:

com.app.loader E/loader: onLoadFinished:

這里只回調(diào)了 onLoadFinished 的方法,把異步操作產(chǎn)生的數(shù)據(jù)給傳遞出來。請注意,這里沒有走 loadInBackground 方法,說明此時 onLoadFinished 回傳的數(shù)據(jù),是舊數(shù)據(jù),也就是上一次異步產(chǎn)生的數(shù)據(jù)。

但是有時我們想丟棄舊數(shù)據(jù)然后重新開始創(chuàng)建一個新Loader,這可怎么辦呢?別擔心,要丟棄舊數(shù)據(jù)調(diào)用restartLoader()即可。

  • restartLoader 方法探究。

點擊 開始查詢按鈕 ,會執(zhí)行下面的代碼

//開始查詢 String tag = editText.getText().toString() ; Bundle bundle = new Bundle(); bundle.putString("key", tag ); getLoaderManager().restartLoader( loaderId , bundle, loaderCallbacks );

Log 日志:

com.app.loader E/loader: onCreateLoader: com.app.loader E/loader: onStartLoading: com.app.loader E/loader: loadInBackground: com.app.loader E/loader: onLoadFinished:

通過日志可以看出 restartLoader重新執(zhí)行了 onCreateLoader 創(chuàng)建了一個新的 Loader 對象; loadInBackground 丟棄了舊數(shù)據(jù),重新加載了新數(shù)據(jù) , 并且回調(diào) onLoadFinished 。

  • 當前 Activity 從后臺到前臺

在測試的時候,我發(fā)現(xiàn)當前 Activity 從后臺到前臺的時候,調(diào)用順序如下:

com.app.loader E/loader: onStartLoading: com.app.loader E/loader: activity onResume: com.app.loader E/loader: loadInBackground: com.app.loader E/loader: onLoadFinished:

可以看到當前界面從后臺到前臺的過程中,Loader 會自動調(diào)異步任務,并且回調(diào)新的數(shù)據(jù)。

  • 當前 Activity 銷毀

當前 Activity 銷毀的時候,調(diào)用順序如下:

com.app.loader E/loader: activity onPause: com.app.loader E/loader: activity onDestroy: com.app.loader E/loader: onLoaderReset:

可以看到 LoaderCallbacks 的 onLoaderReset 方法會回調(diào)。

當 onLoaderReset 方法被調(diào)用的時候,代表 這個 Loader 正在被重置,此時的數(shù)據(jù)不可用。應用程序應該在這一點上刪除對Loader數(shù)據(jù)的任何引用。

比如:

@Overridepublic void onLoaderReset(Loader loader) {Log.e( "loader", "onLoaderReset: ");//當 Activity OnDestory() , 系統(tǒng)會回調(diào)這個方法adapter.swapCursor(null);}

參考文檔:

官方文檔

使用CursorLoader執(zhí)行查詢?nèi)蝿?/p>

Android應用Loaders全面詳解及源碼淺析

Android之Loader介紹

總結

以上是生活随笔為你收集整理的Android Loader 异步加载详解二:探寻Loader内部机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品乱码一区内射人妻无码 | 国产又黄视频 | 激情五月视频 | 欧美精品免费一区二区 | 毛片亚洲av无码精品国产午夜 | 999国产 | 国产成人精品一区二区三区网站观看 | 激情综合文学 | 成人午夜电影网站 | 成年人在线播放 | 无码精品人妻一区二区三区影院 | 黄页网站免费在线观看 | 黄色污污视频软件 | 国产精品久久久久久婷婷天堂 | 九九亚洲视频 | 欧美精品亚洲精品 | 成人在线日韩 | 中文亚洲av片不卡在线观看 | 秋霞欧美一区二区三区视频免费 | 在线能看的av | 亚洲第一天堂在线观看 | 亚洲老妇色熟女老太 | 影音资源av | 欧美黄色网 | 国产精品九九视频 | 一区二区三区四区免费视频 | 国产午夜一区二区三区 | 男人天堂一区 | 一区在线观看视频 | 欧美黑人性猛交xxxx | 国产真实自拍 | 人人爽人人草 | 欧洲-级毛片内射 | 精品久久成人 | 国产在线观看a | 国产18p| 无码国模国产在线观看 | 波多在线播放 | 久久国产精彩视频 | 爱情岛论坛亚洲品质自拍 | 美女露出粉嫩尿囗让男人桶 | 毛片网站免费观看 | 色老头在线一区二区三区 | 国产乱人伦精品一区二区 | 国产艳俗歌舞表演hd | 国产女主播一区二区 | 亚洲va韩国va欧美va精品 | 青青欧美 | 国产视频一区二区三区四区五区 | 亚洲毛片网 | 少妇厨房愉情理伦bd在线观看 | 特大黑人巨交吊性xxxx视频 | 亚洲男人精品 | 精品免费久久久 | 国产夫绿帽单男3p精品视频 | 美女视频一区二区三区 | 一区二区高清视频 | 欧美一级在线观看 | 亚洲视频一区 | 粗了大了 整进去好爽视频 日本女优中文字幕 | 911久久| 亚洲一区二区人妻 | 国产成人无码a区在线观看视频 | 国产亚洲精品成人av在线 | 丁香婷婷六月天 | 精品视频一二三区 | 91麻豆成人精品国产 | 黄色av一区二区三区 | 中文字幕国产视频 | 天天操天天操天天操天天操 | 美女光屁屁露胸胸 | 肉丝袜脚交视频一区二区 | 91久久久久 | 三级黄色短视频 | 日本做爰全过程免费看 | 国产九九热 | 久久最新免费视频 | 欧美日韩在线视频一区 | 六月丁香激情综合 | 777精品伊人久久久久大香线蕉 | 色天天av | 国产最新精品视频 | 精品黑人一区二区三区 | 国产一区在线观看免费 | 国产精品17p | av动漫免费看 | 91精品久久久久久久久久久 | 香蕉视频啪啪 | 日本japanese丰满白浆 | 96久久久| 老牛影视av一区二区在线观看 | 51精品国产人成在线观看 | 天堂av日韩 | 娇妻高潮浓精白浆xxⅹ | 午夜一区二区三区免费观看 | 秋霞欧美视频 | 那里可以看毛片 | 亚洲一区二区三区在线观看视频 | 嫩草在线观看 |