• TouTiao开源项目 分析笔记5


    1.深入理解RxJava

    1.1.基本上现在的APP都会有请求网络,然后处理回调的业务吧。

      如果请求的数据很多,业务越来越复杂,怎么处理呢?

      这里我用到了RxJava来帮我处理业务。

      RxJava主要复杂事件的通知和订阅。这个挺起来没有什么概念。

      其实说白了,RxJava就是优雅地处理函数回调。

    1.2.推荐参考文章:我们为什么要用rxjava?

      这篇文章以一个案例的方式,详细解释了rxjava的功能。

      下面我来深入分析一下。

    1.3.以通常思维模式来处理这个案例。

      

      这个比较好理解,但是这种方式不是异步请求。现在网络请求基本都要异步线程调用。

    1.4.那么修改一下实现方式。

      

    1.5.有匿名类,然后消除

      

      这里将Callback<T>封装起来为一个Task<T>任务了。

    1.6.处理逻辑层

      

    1.7.定义一个抽象类AbstractTask<T> 来实现Task<T>

      

    1.8.最终业务层

      


    2.自定义RxBus

    2.1.参考文章:Android RxJava实现RxBus。

      源代码:

    package com.meiji.toutiao;
    
    import android.support.annotation.NonNull;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ConcurrentHashMap;
    
    import io.reactivex.Observable;
    import io.reactivex.subjects.PublishSubject;
    import io.reactivex.subjects.Subject;
    
    /**
     * https://juejin.im/entry/58ff2e26a0bb9f0065d2c5f2
     */
    
    
    public class RxBus {
    
        private ConcurrentHashMap<Object, List<Subject>> subjectMapper =
                new ConcurrentHashMap<>();
    
        private RxBus() {
    
        }
    
        private static class Holder {
            private static RxBus instance = new RxBus();
        }
    
        @NonNull
        public static RxBus getInstance() {
            return Holder.instance;
        }
    
        @NonNull
        public <T> Observable<T> register(@NonNull Class<T> clz) {
            return register(clz.getName());
        }
    
        @NonNull
        public <T> Observable<T> register(@NonNull Object tag) {
            List<Subject> subjectList = subjectMapper.get(tag);
            if (null == subjectList) {
                subjectList = new ArrayList<>();
                subjectMapper.put(tag, subjectList);
            }
    
            Subject<T> subject = PublishSubject.create();
            subjectList.add(subject);
    
            //System.out.println("注册到rxbus");
            return subject;
        }
    
        public <T> void unregister(@NonNull Class<T> clz, @NonNull Observable observable) {
            unregister(clz.getName(), observable);
        }
    
        public void unregister(@NonNull Object tag, @NonNull Observable observable) {
            List<Subject> subjects = subjectMapper.get(tag);
            if (null != subjects) {
                subjects.remove(observable);
                if (subjects.isEmpty()) {
                    subjectMapper.remove(tag);
                    //System.out.println("从rxbus取消注册");
                }
            }
        }
    
        public void post(@NonNull Object content) {
            post(content.getClass().getName(), content);
        }
    
        public void post(@NonNull Object tag, @NonNull Object content) {
            List<Subject> subjects = subjectMapper.get(tag);
            if (!subjects.isEmpty()) {
                for (Subject subject : subjects) {
                    subject.onNext(content);
                }
            }
        }
    
    }
    View Code

    2.2.定义一个ConcurrentHashMap。

      顾名思义,类似于HashMap,用来临时存储数据的。而且处理了一些多线程安全之类的东西。

    private ConcurrentHashMap<Object, List<Subject>> subjectMapper = 
                new ConcurrentHashMap<>();

    2.3.然后是新建一个实例

        private RxBus() {}
    
        private static class Holder {
            private static RxBus instance = new RxBus();
        }
    
        @NonNull
        public static RxBus getInstance() {
            return Holder.instance;
        }

    2.4. 注册的两个方法

    @NonNull
        public <T> Observable<T> register(@NonNull Class<T> clz) {
            return register(clz.getName());
        }
    
        @NonNull
        public <T> Observable<T> register(@NonNull Object tag) {
            List<Subject> subjectList = subjectMapper.get(tag);
            if (null == subjectList) {
                subjectList = new ArrayList<>();
                subjectMapper.put(tag, subjectList);
            }
    
            Subject<T> subject = PublishSubject.create();
            subjectList.add(subject);
    
            //System.out.println("注册到rxbus");
            return subject;
        }

      传入一个Class<T>参数

      或传入一个Object 参数

      返回一个Observable<T>类型数据

      这里返回一个Subject<T>类型数据

    2.5.反注册的两个方法 

     public <T> void unregister(@NonNull Class<T> clz, @NonNull Observable observable) {
            unregister(clz.getName(), observable);
        }
    
        public void unregister(@NonNull Object tag, @NonNull Observable observable) {
            List<Subject> subjects = subjectMapper.get(tag);
            if (null != subjects) {
                subjects.remove(observable);
                if (subjects.isEmpty()) {
                    subjectMapper.remove(tag);
                    //System.out.println("从rxbus取消注册");
                }
            }
        }

      传入两个参数:Class<T> clz,Observable observable

      或传入两个参数:Object tag,Observable obervable

      调用subjectMapper的remove(tag)方法来取消注册。

    2.6.两个post方法

        public void post(@NonNull Object content) {
            post(content.getClass().getName(), content);
        }
    
        public void post(@NonNull Object tag, @NonNull Object content) {
            List<Subject> subjects = subjectMapper.get(tag);
            if (!subjects.isEmpty()) {
                for (Subject subject : subjects) {
                    subject.onNext(content);
                }
            }
        }

      传入一个参数Object content

      或传入两个参数:Object tag,Object Content

      调用subject.onNext(content)来post。

      不返回数据。


    3.DatabaseHelper帮助器

    3.1.源代码

    package com.jasonjan.headnews.database.helper;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    import com.jasonjan.headnews.database.table.MediaChannelTable;
    import com.jasonjan.headnews.database.table.NewsChannelTable;
    import com.jasonjan.headnews.database.table.SearchHistoryTable;
    import com.jasonjan.headnews.global.InitApp;
    
    /**
     * Created by JasonJan on 2017/12/4.
     */
    
    public class DatabaseHelper extends SQLiteOpenHelper{
    
        private static final String DB_NAME = "Toutiao";
        private static final int DB_VERSION = 5;
        private static final String CLEAR_TABLE_DATA = "delete from ";
        private static final String DROP_TABLE = "drop table if exists ";
        private static DatabaseHelper instance = null;
        private static SQLiteDatabase db = null;
    
        private DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
            super(context, name, factory, version);
        }
    
        private static synchronized DatabaseHelper getInstance() {
            if (instance == null) {
                instance = new DatabaseHelper(InitApp.AppContext, DB_NAME, null, DB_VERSION);
            }
            return instance;
        }
    
        public static synchronized SQLiteDatabase getDatabase() {
            if (db == null) {
                db = getInstance().getWritableDatabase();
            }
            return db;
        }
    
        public static synchronized void closeDatabase() {
            if (db != null) {
                db.close();
            }
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(NewsChannelTable.CREATE_TABLE);
            db.execSQL(MediaChannelTable.CREATE_TABLE);
            db.execSQL(SearchHistoryTable.CREATE_TABLE);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            switch (oldVersion) {
                case 1:
                    db.execSQL(MediaChannelTable.CREATE_TABLE);
                    break;
                case 2:
                    db.execSQL(CLEAR_TABLE_DATA + NewsChannelTable.TABLENAME);
                    break;
                case 3:
                    ContentValues values = new ContentValues();
                    values.put(NewsChannelTable.ID, "");
                    values.put(NewsChannelTable.NAME, "推荐");
                    values.put(NewsChannelTable.IS_ENABLE, 0);
                    values.put(NewsChannelTable.POSITION, 46);
                    db.insert(NewsChannelTable.TABLENAME, null, values);
                    break;
                case 4:
                    db.execSQL(SearchHistoryTable.CREATE_TABLE);
                    break;
            }
        }
    }

      synchronized关键字:加了同步锁,保证线程同步。


    4.三张原始表

    4.1.NewsChannelTable

    public class NewsChannelTable {
        /**
         * 新闻频道信息表
         */
        public static final String TABLENAME = "NewsChannelTable";
    
        /**
         * 字段部分
         */
        public static final String ID = "id";
        public static final String NAME = "name";
        public static final String IS_ENABLE = "isEnable";
        public static final String POSITION = "position";
    
        /**
         * 字段ID 数据库操作建立字段对应关系 从0开始
         */
        public static final int ID_ID = 0;
        public static final int ID_NAME = 1;
        public static final int ID_ISENABLE = 2;
        public static final int ID_POSITION = 3;
    
        /**
         * 创建表
         */
        public static final String CREATE_TABLE = "create table if not exists " + TABLENAME + "(" +
                ID + " text primary key, " +
                NAME + " text, " +
                IS_ENABLE + " text default '1', " +
                POSITION + " text) ";
    }
    View Code

    4.2.MediaChannelTable

    public class MediaChannelTable {
        /**
         * 头条号信息表
         */
        public static final String TABLENAME = "MediaChannelTable";
    
        /**
         * 字段部分
         */
        public static final String ID = "id";
        public static final String NAME = "name";
        public static final String AVATAR = "avatar";
        public static final String TYPE = "type";
        public static final String FOLLOWCOUNT = "followCount";
        public static final String DESCTEXT = "descText";
        public static final String URL = "url";
    
        /**
         * 字段ID 数据库操作建立字段对应关系 从0开始
         */
        public static final int ID_ID = 0;
        public static final int ID_NAME = 1;
        public static final int ID_AVATAR = 2;
        public static final int ID_TYPE = 3;
        public static final int ID_FOLLOWCOUNT = 4;
        public static final int ID_DESCTEXT = 5;
        public static final int ID_URL = 6;
    
        /**
         * 创建表
         */
        public static final String CREATE_TABLE = "create table if not exists " + TABLENAME + "(" +
                ID + " text primary key, " +
                NAME + " text, " +
                AVATAR + " text, " +
                TYPE + " text, " +
                FOLLOWCOUNT + " text, " +
                DESCTEXT + " text, " +
                URL + " text) ";
    }
    View Code

    4.3.SearchHistoryTable

    public class SearchHistoryTable {
        /**
         * 浏览记录表
         */
        public static final String TABLENAME = "SearchHistoryTable";
    
        /**
         * 字段部分
         */
        public static final String ID = "id";
        public static final String KEYWORD = "keyWord";
        public static final String TIME = "time";
    
        /**
         * 字段ID 数据库操作建立字段对应关系 从0开始
         */
        public static final int ID_ID = 0;
        public static final int ID_KEYWORD = 1;
        public static final int ID_TIME = 2;
    
        /**
         * 创建表
         */
        public static final String CREATE_TABLE = "create table if not exists " + TABLENAME + "(" +
                ID + " text auto_increment, " +
                KEYWORD + " text primary key, " +
                TIME + " text) ";
    }
    View Code

      这三张表示基础表。和数据缓存有关系。   



    既然选择了,便不顾风雨兼程。Just follow yourself.
  • 相关阅读:
    团队-团队编程项目作业名称-最终程序
    《团队-中国象棋-项目总结》
    课后作业-阅读任务-阅读提问-4
    《20171130-构建之法:现代软件工程-阅读笔记4》
    《软件工程课程总结》
    《20171117-构建之法:现代软件工程-阅读笔记-3》
    -课后作业-阅读任务-阅读提问-3
    《团队-中国象棋-团队一阶段互评》
    《团队-中国象棋-开发文档》
    《结对-贪吃蛇-结对项目总结》
  • 原文地址:https://www.cnblogs.com/Jason-Jan/p/7976383.html
Copyright © 2020-2023  润新知