Loader是android5.1新增加的api,相容到android3.0系統。有兩個子類CursorLoader和AsyncTaskLoader,CursorLoader主要是用通路系統Uri和資料庫等,AsyncTaskLoader也可以完成cursorLoader的工作,異步loader一般自定義用來加載網絡資料。
Loader有個最重要的特點就是能預設的緩存資料,已經加載過的不會重新加載,當然也可以人為的控制重新加載。Loader常用在橫豎屏切換的時候資料不會第二次加載,節省資源和流量。
下面是橫豎切換效果,資料隻被加載一次
//布局就是一個listview,模拟網絡請求加載xml的string數組
<resources>
<string name="app_name">LoaderDemo</string>
<array name="testData" >
<item>三國演義</item>
<item>水浒傳</item>
<item>西遊記</item>
<item>浮生六記</item>
<item>百草園</item>
<item>三味書屋義</item>
<item>霸王卸甲</item>
</array>
</resources>
//這裡是MainActivity的代碼
public class MainActivity extends AppCompatActivity {
private ListView listView;
private MyAdapter adapter;
final String TAG = "=11 test 11=";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = ((ListView) findViewById(R.id.listView));
adapter = new MyAdapter(this);
listView.setAdapter(adapter);
//初始化loader,第一個參數是loaderID,第二個是Boundle,第三個是回調
getSupportLoaderManager().initLoader(, null, callbacks);
}
private LoaderManager.LoaderCallbacks<List<String>> callbacks = new LoaderManager.LoaderCallbacks<List<String>>() {
@Override
public Loader<List<String>> onCreateLoader(int id, Bundle args) {
Log.i(TAG, "onCreateLoader: ==");//Loader建立的回調
return new MyLoader(getApplicationContext());
}
@Override
public void onLoadFinished(Loader<List<String>> loader, List<String> data) {
Log.i(TAG, "onLoadFinished: ==");//資料加載完成回調
adapter.swapData(data);
}
@Override
public void onLoaderReset(Loader<List<String>> loader) {
Log.i(TAG, "onLoaderReset:== ");
//loader被銷毀了,不再顯示任何資料
adapter.swapData(Collections.<String>emptyList());
}
};
private class MyAdapter extends BaseAdapter {
private Context mContext;
private List<String> list = new ArrayList<>();
MyAdapter(Context context) {
mContext = context;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(android.R.layout.simple_expandable_list_item_1, listView, false);
holder.textTest = (TextView) convertView.findViewById(android.R.id.text1);
convertView.setTag(holder);
}
ViewHolder tag = (ViewHolder) convertView.getTag();
tag.textTest.setText(list.get(position));
return convertView;//還記得這個不,純手撸
}
private void swapData(List<String> data) {
list.clear();
list.addAll(data);
notifyDataSetChanged();
}
private class ViewHolder {
TextView textTest;
}
}
}
//核心部分,自定義異步loader
/**
* 自定義loader加載器<D>,為傳回值類型
* Created by Administrator on 2017/7/27.
*/
class MyLoader extends AsyncTaskLoader<List<String>> {
private Context mContext;
final String TAG = "=22test11=";
//異步loader最核心的就是緩存資料
List<String> cacheData;
MyLoader(Context context) {
super(context);
mContext = context;
}
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what==) {
Toast.makeText(mContext,"子線程加載資料",Toast.LENGTH_LONG).show();
}
}
};
@Override
protected void onStartLoading() {
if (cacheData == null) {
//沒有緩存資料,第一次加載
forceLoad();
}else {
super.deliverResult(cacheData);
}
Log.i(TAG, "onStartLoading: ");
}
@Override
public List<String> loadInBackground() {
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage();
String threadName = Thread.currentThread().getName();
Log.i(TAG, "loadInBackground: " + threadName);
String[] data = mContext.getResources().getStringArray(R.array.testData);
return Arrays.asList(data);
}
@Override
protected void onReset() {
super.onReset();
Log.i(TAG, "onReset: ");
}
@Override
public void deliverResult(List<String> data) {
//加載的資料進行緩存複用
cacheData=data;
super.deliverResult(cacheData);
}
}