【移动应用开发技术】Android 3.0中怎么引入Loader异步加载机制_第1页
【移动应用开发技术】Android 3.0中怎么引入Loader异步加载机制_第2页
【移动应用开发技术】Android 3.0中怎么引入Loader异步加载机制_第3页
【移动应用开发技术】Android 3.0中怎么引入Loader异步加载机制_第4页
【移动应用开发技术】Android 3.0中怎么引入Loader异步加载机制_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】Android3.0中怎么引入Loader异步加载机制

本篇文章给大家分享的是有关Android3.0中怎么引入Loader异步加载机制,在下觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着在下一起来看看吧。Loader是谷歌在Android3.0引入的异步加载机制,能够对数据异步加载并显示到Activity或Fragment上,使用者不需要对数据的生命周期进行管理,而是交给Loader机制来管理。使用Loader的优点假如我们需要从网络上获取数据,通常的做法是使用子线程Thread+Handler或者是使用AsyncTask来处理。Thread+Handler方法实现起来简单直观,不过会麻烦点,需要自己实现Handler子类,创建线程,还要管理Handler的生命周期。AsyncTask实现起来会简单些,无需自己管理线程和Handler。但是要管理AsyncTask的生命周期,要对Activity退出时的情况进行处理。否则可能会出现异常或内存泄露。使用Loader无需关心线程和Handler的创建和销毁,也无需自己管理数据整个的生命周期,Loader机制会自动帮我们处理好。我们唯一要处理的就是数据本身。Loader使用的步骤:创建FragmentActivity或Fragment持有LoaderManager的实例实现Loader,用来加载数据源返回的数据实现LoaderManager.LoaderCallbacks接口实现数据的展示提供数据的数据源,如ContentProvider,服务器下发的数据等几个相关的类LoaderManager管理Loader实例,并使之和FragmentActiivty或Fragment关联上一个Activity或Fragment有一个唯一的LoaderManager实例一个LoaderManager实例可以管理多个Loader实例可以在FragmentActivity或Fragmeng中使用getSupportLoaderManager()获取到LoaderManager实例可以使用initLoader()或restartLoader()方法开始进行数据的加载//0,为唯一的ID,可以为任意整数,为Loader的唯一标识

//null,为Bundle类型,可以向Loader传递构造参数

//LoaderCallbacks,LoaderManager对Loader各事件的调用,参考下面讲到的

LoaderManager.LoaderCallbacks

getSupportLoaderManager().initLoader(0,

null,

new

LoaderCallbacks<D>());LoaderManager.LoaderCallbacksLoaderManager对Loader各种情况的回调接口,包含三个回调方法onCreateLoader(int,Bundle)在这里需要自己创建Loader对象,int为Loader的唯一标识,Bundle为Loader的构造参数,可为空...

new

LoaderManager.LoaderCallbacks<String>()

{

@Override

public

Loader<String>

onCreateLoader(int

id,

Bundle

args)

{

return

new

MyLoader();

}

...

}onLoadFinished(Loader<D>,D)当LoaderManager加载完数据时回调此方法,在这里用UI展示数据给用户。D为泛型,根据实际情况设置为所需的数据类型。和initLoader()LoaderCallbacks<D>参数中的的泛型为同一类型new

LoaderManager.LoaderCallbacks<String>()

{

...

@Override

public

void

onLoadFinished(Loader<String>

loader,

String

data)

{

show(data);

}

...

}onLoaderReset(Loader<D>)当之前创建的Loader实例被重置的时候会回调此方法,此时需要对相关的数据进行清除处理new

LoaderManager.LoaderCallbacks<String>()

{

...

@Override

public

void

onLoaderReset(Loader<String>

loader)

{

show(null);

}

...

}

Loader从数据源获取数据,并对数据进行加载,为抽象类,需要自己实现子类或使用官方已经实现的两个子类AsyncTaskLoader(继承此类的时候会遇到一个坑,见下面的分析)处理异步获取数据CursorLoader处理ContentProvider返回的数据实现AsyncTaskLoader遇到的一个坑首先自定义一个MyAsyncTaskLoader,继承AsyncTaskLoader,会发现需要实现参数为Context的构造方法和实现loadInBackground()抽象方法//继承AsyncTaskLoader类,里面的泛型为返回的数据的类型,这里设为String

public

class

MyAsyncTaskLoader

extends

AsyncTaskLoader<String>{

public

MyAsyncTaskLoader(Context

context)

{

super(context);

}

@Override

public

String

loadInBackground()

{

//模拟加载

try

{

Thread.sleep(3000);

}

catch

(InterruptedException

e)

{

e.printStackTrace();

}

//返回获取到的数据

return

new

String("MyAsyncTaskLoader

Test

Result");

}

}创建FragmentActivitypublic

class

BaseActivity

extends

AppCompatActivity

implements

LoaderManager.LoaderCallbacks{

@Override

protected

void

onCreate(@Nullable

Bundle

savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.base_activity_layout);

//

addFragment();

log("onCreate");

loadData();

}

protected

void

loadData(){

Log.e(getClassName(),"call");

getSupportLoaderManager().initLoader(0,

null,

this);

}

protected

String

getClassName(){

return

getClass().getSimpleName();

}

@Override

public

Loader

onCreateLoader(int

id,

Bundle

args)

{

Log.e(getClassName(),"onCreateLoader");

return

new

MyAsyncTaskLoader(BaseActivity.this);

}

@Override

public

void

onLoadFinished(Loader

loader,

Object

data)

{

Log.e(getClassName(),"data:"+data);

}

@Override

public

void

onLoaderReset(Loader

loader)

{

}

}当运行的时候发现日志值打印了onCreate,call,onCreateLoader,而预期中的MyAsyncTaskLoaderTestResult并没有输出,也就是说onLoadFinished并未被回调。调试发现MyAsyncTaskLoader中的loadInBackground()方法也未执行。这个是怎么回事呢?那么只好查看源码了,这里所使用的都是support-v4的包。查看AsyncTaskLoader源码发现loadInBackground()方法的确为abstract类型,其被调用的地方是在一个叫做LoadTask的内部类中。//可以把

ModernAsyncTask

看做

AsyncTask

final

class

LoadTask

extends

ModernAsyncTask<Void,

Void,

D>

implements

Runnable

{

@Override

protected

D

doInBackground(Void...

params)

{

...

D

data

=

AsyncTaskLoader.this.onLoadInBackground();

...

}

}并且作为AsyncTaskLoader的一个全局变量。public

abstract

class

AsyncTaskLoader<D>

extends

Loader<D>

{

volatile

LoadTask

mTask;

}mTask实例化和被执行的地方在onForceLoad()方法里...

@Override

protected

void

onForceLoad()

{

...

mTask

=

new

LoadTask();

...

executePendingTask();

}

...

void

executePendingTask()

{

...

if

(mUpdateThrottle

>

0)

{

...

mHandler.postAtTime(mTask,

mLastLoadCompleteTime+mUpdateThrottle);

return;

}

}

...

mTask.executeOnExecutor(mExecutor,

(Void[])

null);

}

}mHandler.postAtTime或者是mTask.executeOnExecutor这两个地方就是执行TaskLoader的地方,并会调用到doInBackground()方法。那么到这里我们可以猜测我们自定义的MyAsyncLoader的loadInBackground()未被执行,那么onForceLoad()也应该未被执行。沿着这条线索查找看看这个onForceLoad()是在哪里被调用的。发现其是在AsyncLoader的父类Loader中的forceLoad()中被调用public

class

Loader{

...

public

void

forceLoad()

{

onForceLoad();

}

...

}然后又看到注释发现,此方法只能在loader开始的时候调用,还是找不到什么头绪。突然想到好像CursorLoader没有这个问题,那么看看它是不是有调用forceLoad(),找了下,发现还果然有!是在onStartLoading()这个方法里,并且只有这里调用!public

class

CursorLoader

extends

AsyncTaskLoader<Cursor>

{

...

@Override

protected

void

onStartLoading()

{

if

(mCursor

!=

null)

{

deliverResult(mCursor);

}

if

(takeContentChanged()

||

mCursor

==

null)

{

forceLoad();

}

}

...

}那么我模仿下这个看看是不是真的能行,MyAsyncLoader的代码修改如下://继承AsyncTaskLoader类,里面的泛型为返回的数据的类型,这里设为String

public

class

MyAsyncTaskLoader

extends

AsyncTaskLoader<String>{

public

MyAsyncTaskLoader(Context

context)

{

super(context);

}

//添加了这段代码

@Override

protected

void

onStartLoading()

{

forceLoad();

}

@Override

public

String

loadInBackground()

{

//模拟加载

try

{

Thread.sleep(3000);

}

catch

(InterruptedException

e)

{

e.printStackTrace();

}

//返回获取到的数据

return

n

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论