• Android Loader 机制


    简介

      Loaders机制是在Android3.0 版本之后引入的异步加载数据的方法,能解决长时间加载数据的问题

    特点

      1.适用于任何Activity和Fragment

      2.提供了异步加载数据的机制

      3.检测数据源,当数据源的内容改变是他们能够传递新的结果

    相关API

      LoaderManager:管理Loader,每个Activity或Fragment都对应一个LoaderManager

      LoaderCallbacks:包含和Loader相关的回调方法

      AsyncTaskLoader:抽象类,提供异步加载的方法

      Cursors Loader:AsyncTaskLoader的子类,提供游标数据的加载,本地数据库数据的加载

    案例:使用Loader加载本地联系人:

    package com.hejun.loader;
    
    import android.Manifest;
    import android.content.pm.PackageManager;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.app.LoaderManager;
    import android.support.v4.content.ContextCompat;
    import android.support.v4.content.CursorLoader;
    import android.support.v4.content.Loader;
    import android.support.v7.app.AppCompatActivity;
    import android.text.Editable;
    import android.text.TextUtils;
    import android.text.TextWatcher;
    import android.widget.CursorAdapter;
    import android.widget.EditText;
    import android.widget.ListView;
    import android.widget.SimpleCursorAdapter;
    
    import butterknife.BindView;
    import butterknife.ButterKnife;
    
    public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
    
        //绑定资源
        @BindView(R.id.listView)
        ListView listView;
        @BindView(R.id.ed)
        EditText ed;
        private SimpleCursorAdapter cursorAdapter;
        private LoaderManager loaderManager;
        private String content;
        private Uri contentUri;
        private CursorLoader cursorLoader;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ButterKnife.bind(this);
            requestPermission();
            //获取loaderManager对象
            loaderManager = getSupportLoaderManager();
            //初始化Loader 参数1 ID 参数2 传递的参数 参数3 LoaderCallbacks 回调接口
            loaderManager.initLoader(0, null, this);
            cursorAdapter = new SimpleCursorAdapter(this,
                    android.R.layout.activity_list_item,
                    null,
                    new String[]{ContactsContract.Contacts.DISPLAY_NAME},
                    new int[]{android.R.id.text1},
                    CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
            listView.setAdapter(cursorAdapter);
            ed.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    content = s.toString();
                    //重新加载Loader
                    loaderManager.restartLoader(0,null,MainActivity.this);
                }
    
                @Override
                public void afterTextChanged(Editable s) {
    
                }
            });
        }
    
        /**
         * 创建Loader对象
         *
         * @param i
         * @param bundle
         * @return
         */
        @NonNull
        @Override
        public Loader<Cursor> onCreateLoader(int i, @Nullable Bundle bundle) {
            contentUri = ContactsContract.Contacts.CONTENT_URI;
            if (!TextUtils.isEmpty(content)){
                contentUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,Uri.encode(content));
    
            }
            cursorLoader = new CursorLoader(this, contentUri, null, null, null, null);
            return cursorLoader;
        }
    
        /**
         * 在UI线程中运行,加载数据完成后,更新UI
         *
         * @param loader
         * @param cursor
         */
        @Override
        public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor cursor) {
            //在主线程中完成, 切换cursorAdapter中的游标
            cursorAdapter.swapCursor(cursor);
        }
    
        /**
         * 重置Loader
         *
         * @param loader
         */
        @Override
        public void onLoaderReset(@NonNull Loader<Cursor> loader) {
            //销毁游标
            cursorAdapter.swapCursor(null);
        }
        //动态申请权限
        private void requestPermission() {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS},
                        0);//申请权限
    
    
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            switch (requestCode) {
                case 0:
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        return;
                    } else {
                        finish();
                    }
                    break;
            }
        }
    }

    自定义Loader:使用Loader加载自定义数据类型

      步骤:

      1.继承AsycnTaskLoader类

      2.实现loadInBackground方法

      3.使用LoadManager初始化Loader  

      4.在LoaderCallbacks接口的OnCreateLoader方法中返回自定义Loader

    案例:从网上加载用户信息(name password)

    用户类

    class Userbean {
    
        private String name;
    
        private String password;
    
        public Userbean(String name, String password) {
            this.name = name;
            this.password = password;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }

    自定义Loader

    package com.hejun.loader;
    
    import android.content.Context;
    import android.os.AsyncTask;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.content.AsyncTaskLoader;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 自定义Loader,加载UserBean数据集合
     */
    public class LoaderUser extends AsyncTaskLoader<List<Userbean>> {
    
        public LoaderUser(@NonNull Context context) {
            super(context);
        }
    
        @Override
        protected void onStartLoading() {
            super.onStartLoading();
            //Loader开始执行后,强制调用loadInBackground()方法
            if (isStarted()){
                forceLoad();
            }
        }
    
        /**
         * 在子线程中加载数据
         * @return
         */
        @Nullable
        @Override
        public List<Userbean> loadInBackground() {
            //模拟从网上获取数据
            List<Userbean> users = new ArrayList<>();
            users.add(new Userbean("zhangsan","123456"));
            users.add(new Userbean("lisi","123456"));
            users.add(new Userbean("wangwu","123456"));
            users.add(new Userbean("zhaoliu","123456"));
            return users;
        }
    }

    MainActivity:

    package com.hejun.loader;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.LoaderManager;
    import android.support.v4.content.Loader;
    import android.support.v7.app.AppCompatActivity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ListView;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import butterknife.BindView;
    import butterknife.ButterKnife;
    
    public class Main2Activity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Userbean>> {
    
        @BindView(R.id.listView)
        ListView listView;
    
        private List<Userbean> list = new ArrayList<>();
        private Adapter adapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
            ButterKnife.bind(this);
            LoaderManager loaderManager = getSupportLoaderManager();
            loaderManager.initLoader(0, null, this);
            adapter = new Adapter(this);
            listView.setAdapter(adapter);
        }
    
        @NonNull
        @Override
        public Loader<List<Userbean>> onCreateLoader(int i, @Nullable Bundle bundle) {
            //返回自定义Loader
            return new LoaderUser(this);
        }
    
        @Override
        public void onLoadFinished(@NonNull Loader<List<Userbean>> loader, List<Userbean> uerbeanList) {
            adapter.addUsers(uerbeanList);
            adapter.notifyDataSetChanged();
        }
    
        @Override
        public void onLoaderReset(@NonNull Loader<List<Userbean>> loader) {
    
        }
    
        class Adapter extends BaseAdapter {
    
            private Context context;
    
            private List<Userbean> users = new ArrayList<>();
    
            public Adapter(Context context) {
                this.context = context;
            }
    
            public void addUsers(List<Userbean> userList) {
                users.addAll(userList);
                notifyDataSetChanged();
            }
    
            @Override
            public int getCount() {
                return users.size();
            }
    
            @Override
            public Userbean getItem(int position) {
                return users.get(position);
            }
    
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder viewHolder = null;
                if (convertView == null) {
                    convertView = LayoutInflater.from(context).inflate(R.layout.item, parent, false);
                    viewHolder = new ViewHolder(convertView);
                    convertView.setTag(viewHolder);
                } else {
                    viewHolder = (ViewHolder) convertView.getTag();
                }
                Userbean userbean = users.get(position);
                viewHolder.name.setText(userbean.getName());
                viewHolder.password.setText(userbean.getPassword());
                return convertView;
            }
    
            class ViewHolder {
                @BindView(R.id.name)
                TextView name;
                @BindView(R.id.password)
                TextView password;
    
                ViewHolder(View view) {
                    ButterKnife.bind(this, view);
                }
            }
        }
    }

    总结

      可以用CursorsLoader加载数据库,ContentProvider数据

      对于自定义数据类型,可以自定义Loader来实现

      

  • 相关阅读:
    Python selenium —— 一定要会用selenium的等待,三种等待方式解读
    python3 selenium 切换窗口的几种方法
    转:对UI自动化测试的一些感悟
    Docker
    【转】selenium之 定位以及切换frame
    selenium——键盘操作
    selenium——鼠标事件
    python 读取Excel表格方法
    springboot maven 更新jar包速度慢的问题
    Python3 读写utf-8文本文件
  • 原文地址:https://www.cnblogs.com/conglingkaishi/p/10097119.html
Copyright © 2020-2023  润新知