天天看點

Loader之自定義AsyncTaskLoader<D>

Loader是android5.1新增加的api,相容到android3.0系統。有兩個子類CursorLoader和AsyncTaskLoader,CursorLoader主要是用通路系統Uri和資料庫等,AsyncTaskLoader也可以完成cursorLoader的工作,異步loader一般自定義用來加載網絡資料。

Loader有個最重要的特點就是能預設的緩存資料,已經加載過的不會重新加載,當然也可以人為的控制重新加載。Loader常用在橫豎屏切換的時候資料不會第二次加載,節省資源和流量。

下面是橫豎切換效果,資料隻被加載一次

Loader之自定義AsyncTaskLoader<D>
//布局就是一個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);
    }
}