Android----单例模式下的一种整体开发思路

前言

2018/8/9 ,因为涉及到整体的一个开发方式。只是对自己开发思路的一个描述,并不能保证准确,实用,易用。

问题

AsyncTask提供了很大的帮助,但是还是会涉及到内存溢出的问题。

问题1:异步任务的时候为了使用弱引用写了很多重复的代码

例如为了避免使用内部类引用父类,要使用静态内部类,并且要使用弱引用才能控制父类的展示。

问题2:有些时候我们更新一个数据,要改变页面中很多个地方的内容,因为自己的遗漏,导致了数据与显示统一性的问题。

例如通过
好友聊天界面->好友信息界面->好友修改备注界面。修改了好友备注,
返回时候要一层一层 setText(nickname) 保证好友最新的备注被展示。

问题3:有时候更新数据,只是想刷新数据,并不想大张旗鼓,告诉用户现在的状态。

比如用户开始时,获取到本地数据之后,只是想去刷新一下数据,保证数据的最新。

解决思路

问题1:

自定义适合自己代码的异步类,定义好接口,中间使用弱引用的借口作为交互工具。

问题2:

定义所有需要有一定持续性显示的属性为单例类。(每一种数据定义一个单独的单例类),将所有的数据更新事件添加到单例类,在onDestory的时候把数据更新事件从单例类移除。
比如主页显示的内容则应该成为单例类。比如查看某一个好友的更多信息这种只是临时展示一下的内容则不需要成为单例类。
例如在聊天软件中,
1.用户信息(userbean)----用户信息与(个人信息页,修改个人信息页...)有关,并且需要长期显示。
2.好友列表(list<FriendBean>)----好友信息与(好友信息页,好友聊天页,消息页)有关,并需要长期显示。
3.群组列表(list<TeamBean>)----群组信息与(群组信息页,群组聊天页,消息页)有关,并需要长期显示。
4.消息列表(list<ComBean>)----消息列表与(主页是否有新消息,聊天页消息展示,主页消息展示)
5.当前在线状态(boolean onLine)----在线状态与(主要显示是否在线)并需要长期展示状态。
6.好友请求(list<FriendAskBean>)----好友请求与(好友请求页,好友页(点击同意之后),主页展示当前是否有新请求。)有关,并且需要长期提示主页是否有新的请求。
7.群组请求(list<TeamAskBean>)----同上

问题3:

在单例类中把数据操作与数据更新结合,写在一起。在Application类中定义handle,用于接受单例类刷新与之相关的显示的请求。

基本结构

QQ图片20180809103816.png

代码

model
public class Model {

    public List<OnModelChangeListener> listeners;

    public Model() {
        listeners = new LinkedList<>();
    }

    public void actListeners() {
        for (int i = 0; i < listeners.size(); i++) {
            try {
                listeners.get(i).onChange();
            } catch (Exception e) {
                listeners.remove(listeners.get(i));
            }
        }
    }
}
onModelChangeListener
public interface OnModelChangeListener {
    void onChange();
}
AllModel内部定义部分
public class AllModel extends Model {

    public List<RecordBean> recordBeans;

    private static AllModel instance;

    public static AllModel getInstance() {
        if (instance == null){
            instance = new AllModel();
        }
        return instance;
    }

    public int netFlush(){
        try {
            Thread.sleep(2000);
            recordBeans = new ArrayList<>();
            recordBeans.add(new RecordBean(0, "0号", "7:30", "8:00"));
            recordBeans.add(new RecordBean(1, "1号", "8:00", "8:30"));
            recordBeans.add(new RecordBean(2, "2号", "8:30", "9:00"));
            recordBeans.add(new RecordBean(3, "3号", "9:00", "9:30"));
            App.postHandle(App.HANDLE_ALL);
            return App.NET_SUCCEED;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return App.NET_FAILURE;
    }
}
App接受部分
public class App extends Application {

    public static Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == HANDLE_ALL){
                AllModel.getInstance().actListeners();
            }
        }
    };

    public static final int HANDLE_ALL = 100000;
    public static final int HANDLE_MINE = 100001;

    public static void postHandle(int h){
        handler.sendEmptyMessage(h);
    }
}
MainActivity发送部分
   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        initLayout();

        App.postRunnable(new FlushRunnable());
    }

    private static class FlushRunnable implements Runnable{

        @Override
        public void run() {
            AllModel.getInstance().netFlush();
        }
    }
AllFragment数据刷新部分
public class AllFragment extends Fragment {


    private View root;

    private ListView lst;
    private BaseAdapter adapter;

    private FlushOnModelChangeListener flushOnModelChangeListener;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        root = inflater.inflate(R.layout.all, null, false);
        initLayout();

        flushOnModelChangeListener = new FlushOnModelChangeListener();
        AllModel.getInstance().listeners.add(flushOnModelChangeListener);
        return root;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        AllModel.getInstance().listeners.remove(flushOnModelChangeListener);
    }
    private class FlushOnModelChangeListener implements OnModelChangeListener{

        @Override
        public void onChange() {
            adapter.notifyDataSetChanged();
        }
    }
}

demo

https://github.com/pgyCode/ShowModelDemo
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容