【ListViewJson】【MainActivity功能性分析,不讨论具体工具类的实现】【android解析json数据(包含对图片数据的异步缓存处理),并将其加载到listview中】

最近遇到了一个相当好、对初学者相当友善的项目,是描述如何将json数据解析,并加载到listview中。

但是个人认为以后所有类似功能的实现都可以使用这套工具。

项目也可以使用这套架构。

这个项目是处理每个news只有一个imgurl,应该考虑一下当imgurl数量不定的时候具体应该怎么解决。

首先项目源码结构如下:

项目下载链接:http://download.csdn.net/download/y562810463/8004245

 

在这个项目中的com.demo.app.common包完全可以应用在其它的项目中,而com.demo.api,com.demo.app等包也非常具有参考价值。

首先运行结果图:

 

首先来说明一下程序的运行逻辑:

继承Application类的appContext是应用真正的入口,但是appContext的onCreate方法调用了super.onCreate(),

所以从com.demo.app.ui的MainActivity进入。

MainActivity.java代码如下以及逻辑分析:

package com.demo.app.ui;

import java.util.List;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;

import com.demo.app.AppContext;
import com.demo.app.AppException;
import com.demo.app.R;
import com.demo.app.adapter.MainListViewAdapter;
import com.demo.app.bean.News;
import com.demo.app.bean.NewsList;
import com.demo.app.common.UIHelper;
import com.demo.app.widget.MyListView;

public class MainActivity extends Activity {
    private MyListView listview;
    private List<News> newsList;
    private AppContext appContext;// 全局Context
    private MainListViewAdapter listViewAdapter;
    private ProgressDialog selectorDialog;
    private Button bt_news, bt_forum, bt_cartype, bt_favour, bt_more;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        appContext = (AppContext) getApplication();
        // 网络连接判断
        if (!appContext.isNetworkConnected())
            UIHelper.ToastMessage(this, R.string.network_not_connected);
        init();
        initData();
    }

    private void init() {
        bt_news = (Button) findViewById(R.id.bt_news);
        bt_forum = (Button) findViewById(R.id.bt_forum);
        bt_cartype = (Button) findViewById(R.id.bt_cartype);
        bt_favour = (Button) findViewById(R.id.bt_favour);
        bt_more = (Button) findViewById(R.id.bt_more);
        bt_news.setSelected(true);
        bt_news.setOnClickListener(onClick(bt_news));
        bt_forum.setOnClickListener(onClick(bt_forum));
        bt_cartype.setOnClickListener(onClick(bt_cartype));
        bt_favour.setOnClickListener(onClick(bt_favour));
        bt_more.setOnClickListener(onClick(bt_more));
        listview = (MyListView) findViewById(R.id.news_listview);
        selectorDialog = ProgressDialog.show(this, null, "正在加载,请稍候...", true,
                false);

    }

    private View.OnClickListener onClick(final Button btn) {
        return new View.OnClickListener() {
            public void onClick(View v) {

                bt_news.setSelected(false);
                bt_forum.setSelected(false);
                bt_cartype.setSelected(false);
                bt_favour.setSelected(false);
                bt_more.setSelected(false);
                if (btn == bt_news) {
                    bt_news.setSelected(true);
                } else if (btn == bt_forum) {
                    bt_forum.setSelected(true);
                } else if (btn == bt_cartype) {
                    bt_cartype.setSelected(true);
                } else if (btn == bt_favour) {
                    bt_favour.setSelected(true);
                } else if (btn == bt_more) {
                    bt_more.setSelected(true);
                }
            }
        };
    }

    Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            selectorDialog.cancel();
            if (msg.what == 1) {
                newsList = (List<News>) msg.obj;
                listViewAdapter = new MainListViewAdapter(MainActivity.this,
                        newsList);
                listview.setAdapter(listViewAdapter);
            } else if (msg.what == -1) {
                UIHelper.ToastMessage(MainActivity.this, "没有数据");
            } else if (msg.what == -2) {
                UIHelper.ToastMessage(MainActivity.this,
                        R.string.xml_parser_failed);
            }
        }
    };

    private void initData() {

        selectorDialog.show();
        new Thread() {
            public void run() {
                Message msg = new Message();
                boolean isRefresh = false;
                try {
                    NewsList list = appContext.getNewsList();
                    if (list.getNewsCount() > 0) {
                        msg.what = 1;
                        msg.obj = list.getNewslist();
                        appContext.saveObject(list, "newslist_");
                    } else {
                        msg.what = -1;
                    }
                } catch (AppException e) {
                    e.printStackTrace();
                    msg.what = -2;
                    msg.obj = e;
                }
                mHandler.sendMessage(msg);
            }
        }.start();
    }
}

从MainActivity函数onCreate开始分析:

1、首先生成appContext,之后使用AppContext中定义的各种可能用到的方法。

 appContext = (AppContext) getApplication();

2、进行网络判断,其中UIHelper是一个工具类

 if (!appContext.isNetworkConnected())
            UIHelper.ToastMessage(this, R.string.network_not_connected);

3、执行init、initData方法,init方法比较简单,关键是initData方法。

init();
initData();

4、接下来分析 initData方法。因为initData方法与MainActivity中的handler相关,所以放在一起分析它们的作用。

Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            selectorDialog.cancel();
            if (msg.what == 1) {
                newsList = (List<News>) msg.obj;
                listViewAdapter = new MainListViewAdapter(MainActivity.this,
                        newsList);
                listview.setAdapter(listViewAdapter);
            } else if (msg.what == -1) {
                UIHelper.ToastMessage(MainActivity.this, "没有数据");
            } else if (msg.what == -2) {
                UIHelper.ToastMessage(MainActivity.this,
                        R.string.xml_parser_failed);
            }
        }
    };

    private void initData() {

        selectorDialog.show();
        new Thread() {
            public void run() {
                Message msg = new Message();
                boolean isRefresh = false;
                try {
                    NewsList list = appContext.getNewsList();
                    if (list.getNewsCount() > 0) {
                        msg.what = 1;
                        msg.obj = list.getNewslist();
                        appContext.saveObject(list, "newslist_");
                    } else {
                        msg.what = -1;
                    }
                } catch (AppException e) {
                    e.printStackTrace();
                    msg.what = -2;
                    msg.obj = e;
                }
                mHandler.sendMessage(msg);
            }
        }.start();
    }

使用initdata方法去启动一个线程,这个线程去获得要加载的List<News>数据,通过使用appContext.getNewsList()方法。

而appContext.getNewsList()使用ApiClient.getNewsList()方法,ApiClient.getNewsList()方法中涉及如何通过网络获取json字符串并将json转换为List<News>。

如果获取List<News>成功的话,将其放到Message msg的域obj中,并将msg的域what设置为1.返还给handler。

注意:List<News>中的News图片存的是一个url。

当handler获得一个List<News>,它就建立  MainListViewAdapter适配器,而这个适配器将数据解析到listview中。需要注意的一点是:这个适配器中使用BitmapManager将图片的url转换为图片。

 

另外需要注意一点的是:这个应用会将获取到的数据存在缓存中。而adapter会在getView中load一下。

 

下一篇博客具体讨论它的工具类的作用以及实现。

 

posted @ 2014-12-22 16:04  比企谷雪乃  阅读(401)  评论(0编辑  收藏  举报