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

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>
工程目录:

最终效果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值