您的位置:首页 > 理论基础 > 计算机网络

Android Loader(四) 自定义Loader从网络中获取文本数据

2014-11-30 18:11 344 查看
Android Loader(三) 结合CursorLoader分析Loader相关源码

根据文档,自定义Loader需要实现的方法有,onStartLoading(),onStopLoading(), onForceLoad(), onReset()。

实现自定义Loader,很少直接继承Loader,可以继承Loader的子类AsyncTaskLoader,AsyncTaskLoader已经帮我们写好了 onForceLoad异步加载数据的逻辑,由于是从网络获取文本数据,采用Http的get协议访问比较合适,由于HttpGET是短连接,所以onStopLoading和onReset可以不用重写,考虑重写onStartLoading的逻辑即可。

加载数据的Loader: NetworkLoader.java

public class NetworkLoader extends AsyncTaskLoader<String> {

private String result;

public NetworkLoader(Context context) {
super(context);
}

@Override
protected void onStartLoading() {
super.onStartLoading();
if (result != null) {
deliverResult(result);
} else {
forceLoad();
}
}

@Override
public String loadInBackground() {
String url = "http://gc.ditu.aliyun.com/geocoding?a=苏州市";
return doGet(url);
}

private String doGet(String url) {
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent()));

StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();

String page = sb.toString();

return page;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return url;
}
}
onStartLoading方法进行判断,如果需要获取的数据已经存在,则直接调用deliverResult,前篇已经分析过,deliverResult会触发onLoadeFinished回调。如果没有数据,则进行异步加载数据过程,forceLoad内部会启动内部的AsyncTask,最终调用loadInBackground,耗时的加载网络数据的操作写在这里就可以。本例是通过一个URL获取一串字符串,这里URL地址找了个公开的测试接口。

再来看使用这个Loader的Fragment:

MsgFragment.java:

public class MsgFragment<T extends String> extends Fragment implements
LoaderManager.LoaderCallbacks<String> {

private TextView content;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.main, null);
content = (TextView) v.findViewById(R.id.content);
return v;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(0, null, this);
}

@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
return new NetworkLoader(getActivity());
}

@Override
public void onLoadFinished(Loader<String> loader, String data) {
content.setText(data);
}

@Override
public void onLoaderReset(Loader<String> loader) {

}
}
这里在onLoadFinished中处理获取的字符串数据。

接下来就是Activity的代码;

MainActivity.java:

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

FragmentManager fm = getFragmentManager();

if (fm.findFragmentById(android.R.id.content) == null) {
MsgFragment list = new MsgFragment();
fm.beginTransaction().add(android.R.id.content, list).commit();
}
}
}


布局文件就是一个简单的TextView。

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.httploader"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
工程目录:



最终效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: