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

歡迎訪問 生活随笔!

生活随笔

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

数据库

安卓加载mysql数据到列表里_Android如何从数据库中加载海量数据

發布時間:2024/9/30 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 安卓加载mysql数据到列表里_Android如何从数据库中加载海量数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Android3.0之前,很多應用程序響應性能方面有缺陷,其中比較典型的錯誤行為是在UI線程中執行了查詢數據操作,尤其是一次性從database查出大量數據并加載到ListView里,用這種方式載入數據是最差的選擇,硬件偏弱的手機會假死會兒。 其實體驗最好的還屬手機自帶通訊錄App這類應用,滑動絲般順滑。

在Android 3.0版本之前一般的做法是用Activity提供的startManagingCursor()和stopManagingCursor(), ?已經deprecated的API我們就不談了,3.0之后取而代之的是Loader,想必Loader的使用大家都有所知道:public?class?CursorLoaderListFragment?extends?ListFragment?{

SimpleCursorAdapter?mAdapter;

SearchView?mSearchView;

String?mCurFilter;????static?final?String[]?CONTACTS_SUMMARY_PROJECTION?=?new?String[]?{

ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME,

ContactsContract.Contacts.CONTACT_STATUS,

};????private?LoaderManager.LoaderCallbacks?mLoaderCallback?=?new?LoaderManager.LoaderCallbacks()?{????????@Override

public?Loader?onCreateLoader(int?id,?Bundle?args)?{????????????//?This?is?called?when?a?new?Loader?needs?to?be?created.

String?select?=?"(("?+?ContactsContract.Contacts.DISPLAY_NAME?+?"?NOTNULL)?AND?("

+?ContactsContract.Contacts.HAS_PHONE_NUMBER?+?"=1)?AND?("

+?ContactsContract.Contacts.DISPLAY_NAME?+?"?!=?''?))";????????????return?new?CursorLoader(getActivity(),

ContactsContract.Contacts.CONTENT_URI,

CONTACTS_SUMMARY_PROJECTION,?select,?null,

ContactsContract.Contacts.DISPLAY_NAME?+?"?COLLATE?LOCALIZED?ASC");

}????????@Override

public?void?onLoadFinished(@NonNull?Loader?loader,?Cursor?data)?{????????????//?Swap?the?new?cursor?in.??(The?framework?will?take?care?of?closing?the

//?old?cursor?once?we?return.)

mAdapter.swapCursor(data);????????????//?The?list?should?now?be?shown.

if?(isResumed())?{

setListShown(true);

}?else?{

setListShownNoAnimation(true);

}

}????????@Override

public?void?onLoaderReset(@NonNull?Loader?loader)?{????????????//?This?is?called?when?the?last?Cursor?provided?to?onLoadFinished()

//?above?is?about?to?be?closed.??We?need?to?make?sure?we?are?no

//?longer?using?it.

mAdapter.swapCursor(null);

}

};????@Override

public?void?onActivityCreated(Bundle?savedInstanceState)?{????????super.onActivityCreated(savedInstanceState);

setEmptyText("No?phone?numbers");

setHasOptionsMenu(true);

mAdapter?=?new?SimpleCursorAdapter(getActivity(),

android.R.layout.simple_list_item_2,?null,????????????????new?String[]?{?ContactsContract.Contacts.DISPLAY_NAME,?ContactsContract.Contacts.CONTACT_STATUS?},????????????????new?int[]?{?android.R.id.text1,?android.R.id.text2?},?0);

setListAdapter(mAdapter);

LoaderManager.getInstance(this).initLoader(0,?null,?mLoaderCallback);

}????public?boolean?onQueryTextChange(String?newText)?{

String?newFilter?=?!TextUtils.isEmpty(newText)???newText?:?null;????????if?(mCurFilter?==?null?&&?newFilter?==?null)?{????????????return?true;

}????????if?(mCurFilter?!=?null?&&?mCurFilter.equals(newFilter))?{????????????return?true;

}

mCurFilter?=?newFilter;

LoaderManager.getInstance(this).restartLoader(0,?null,?mLoaderCallback);????????return?true;

}

}不難看出只要實現三個回調函數就能創建出一個LoaderCallbacks,并將此丟給LoaderManager去initLoader或者restartLoader,initLoader是第一次查詢使用的,restartLoader是二次查詢使用的。簡單是簡單不過有個東西不知有沒有發現:在此demo 中onCreateLoader()方法返回值是CursorLoader對象,它的構造函數必須是Uri,意味著必須是基于Content Provider實現的數據庫才可以使用,可是現實項目需要ContentProvider的不多吧,很多是純sqlite的,為了此場景硬生生將sqlite的實現改成ContentProvider得不償失。

當翻看onCreateLoader()方法定義時候,發現返回值不是CursorLoader而是Loader,CursorLoader只是Loader的一個子類而已,因此轉機來了:定義一個類繼承Loader并內部用Cursor實現,最終返回自定義類的對象給onCreateLoader():public?abstract?class?SQLiteCursorLoader?extends?AsyncTaskLoader?{????private?Cursor?lastCursor;????private?Cursor?queryCursor;????public?SQLiteCursorLoader(Context?context,?Cursor?cursor)?{????????super(context);

queryCursor?=?cursor;

}????/**

*?Runs?on?a?worker?thread,?loading?in?our?data.?Delegates?the?real?work?to?concrete?subclass'

*?buildCursor()?method.

*/

@Override

public?Cursor?loadInBackground()?{????????final?Cursor?cursor?=?queryCursor;????????if?(cursor?!=?null)?{????????????//?Ensure?the?cursor?window?is?filled

cursor.getCount();

}????????return?cursor;

}????/**

*?Runs?on?the?UI?thread,?routing?the?results?from?the?background?thread?to?whatever?is?using

*?the?Cursor?(e.g.,?a?CursorAdapter).

*/

@Override

public?void?deliverResult(final?Cursor?cursor)?{????????if?(isReset())?{????????????//?An?async?query?came?in?while?the?loader?is?stopped

if?(cursor?!=?null)?{

cursor.close();

}????????????return;

}????????final?Cursor?oldCursor?=?lastCursor;

lastCursor?=?cursor;????????if?(isStarted())?{????????????super.deliverResult(cursor);

}????????if?(oldCursor?!=?null?&&?oldCursor?!=?cursor?&&?!oldCursor.isClosed())?{

oldCursor.close();

}

}????/**

*?Starts?an?asynchronous?load?of?the?list?data.?When?the?result?is?ready?the?callbacks?will?be

*?called?on?the?UI?thread.?If?a?previous?load?has?been?completed?and?is?still?valid?the?result

*?may?be?passed?to?the?callbacks?immediately.?Must?be?called?from?the?UI?thread.

*/

@Override

protected?void?onStartLoading()?{????????if?(lastCursor?!=?null)?{

deliverResult(lastCursor);

}????????if?(takeContentChanged()?||?lastCursor?==?null)?{

forceLoad();

}

}????/**

*?Must?be?called?from?the?UI?thread,?triggered?by?a?call?to?stopLoading().

*/

@Override

protected?void?onStopLoading()?{????????//?Attempt?to?cancel?the?current?load?task?if?possible.

cancelLoad();

}????/**

*?Must?be?called?from?the?UI?thread,?triggered?by?a?call?to?cancel().?Here,?we?make?sure?our

*?Cursor?is?closed,?if?it?still?exists?and?is?not?already?closed.

*/

@Override

public?void?onCanceled(final?Cursor?cursor)?{????????if?(cursor?!=?null?&&?!cursor.isClosed())?{

cursor.close();

}

}????/**

*?Must?be?called?from?the?UI?thread,?triggered?by?a?call?to?reset().?Here,?we?make?sure?our

*?Cursor?is?closed,?if?it?still?exists?and?is?not?already?closed.

*/

@Override

protected?void?onReset()?{????????super.onReset();????????//?Ensure?the?loader?is?stopped

onStopLoading();????????if?(lastCursor?!=?null?&&?!lastCursor.isClosed())?{

lastCursor.close();

}

lastCursor?=?null;

}

}事實上并沒有直接繼承Loader, 而是繼承的AsyncTaskLoader,從名字看就知道它是類似AsyncTask的原理實現的,SDK的CursorLoader也是基于AsyncTaskLoader實現的,當有了SQLiteCursorLoader我們就可以用SQL創建LoaderManager.LoaderCallbacks了:private?LoaderManager.LoaderCallbacks?mLoaderCallback?=?new?LoaderManager.LoaderCallbacks()?{????????@Override

public?Loader?onCreateLoader(int?id,?Bundle?args)?{????????????//?This?is?called?when?a?new?Loader?needs?to?be?created.

String?sql?=?"SELECT?*?FROM?TABLE_XX";????????????return?new?SQLiteCursorLoader(getActivity(),?sql);

}????????@Override

public?void?onLoadFinished(@NonNull?Loader?loader,?Cursor?data)?{????????????//?...

}????????@Override

public?void?onLoaderReset(@NonNull?Loader?loader)?{????????????//?...

}

};關于Android數據庫方面的開發用純SQL的確有點累,可以考慮ORM的思路,以前我也寫了一個輕量級的,也一直使用中,SQLiteCursorLoader其實我提供了2個構造方法,一個如上傳Cursor,另外一個是傳BuilderSupport, 它有2個實現,分別為ConditionBuilder和MultiTableConditionBuilder, 通過他們可以以面向對象方式來查詢數據庫,一個是用于單表查詢,一個用于多表查詢,具體可以參考下:

作者:生活簡單些

鏈接:https://www.jianshu.com/p/4a6bb4cde477

總結

以上是生活随笔為你收集整理的安卓加载mysql数据到列表里_Android如何从数据库中加载海量数据的全部內容,希望文章能夠幫你解決所遇到的問題。

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