快速开发框架dhroid的使用

来源:互联网 发布:淘宝怎么换购产品 编辑:程序博客网 时间:2024/06/05 13:22

由于dhroid已经一年多没更新了,所以有些地方用的不是最新的API,大家慢慢去了解吧。

基本配置

将框架引入项目有三种方式
1. 引入jar包(切换到Project目录,将jar包放到app\libs下)
2. 引入源码(进入到项目文件夹目录,将代码拷贝到app\src\main\java下)
3. 此项目没发布到Maven,就不说了。

此时项目是编译不通过的,需要引入Universal Image Loader作为图片加载库,引入Gson作为解析json数据库,引入httpmime.jar为网络部分做支持。

首先,在dhroid根目录下有两个类Const.javaDhroid.java,作为配置类。

public class Const {    // 打印日志    public static boolean logable = true;    // 打印日志时打印行号    public static boolean logline = true;    // 网络框架中拦截异常,上线时打开    public static boolean net_error_try = false;    // 自动注入    public static boolean auto_inject = true;    // 数据库版本号    public static int DATABASE_VERSION = 1;    //adapter 的分页相关,弃用,后面会说明    public static String netadapter_page_no = "page";    public static String netadapter_step = "step";    public static Integer netadapter_step_default = 20;    public static String netadapter_timeline = "timeline";    public static String netadapter_json_timeline = "id";    public static String netadapter_no_more = "已经没有了";    public static String[] ioc_instal_pkg = null;    //图片缓存相关    public static String image_cache_dir = "dhcache";// 缓存目录    public static int image_cache_num = 12;// 缓存数量    public static Boolean image_cache_is_in_sd = false;    public static long image_cache_time = 100000l;    //网络访问返回数据的格式定义,需要结合后台返回数据格式去做更改    public static String response_success = "success";    public static String response_msg = "msg";    public static String response_data = "data";    public static String response_code = "code";    public static int net_pool_size = 10;}
/** * 完成一些系统的初始化的工作 * @author Administrator */public class Dhroid {    public static void init(Application app) {        Ioc.initApplication(app);        //对话框的配置        Ioc.bind(DialogImpl.class).to(IDialog.class).scope(InstanceScope.SCOPE_PROTOTYPE);        // 配置ImageLoader        ImageLoaderConfiguration imageconfig = new ImageLoaderConfiguration.Builder(                app.getApplicationContext())                .threadPoolSize(3)                .threadPriority(Thread.NORM_PRIORITY - 2)                .memoryCacheSize(1500000)                .denyCacheImageMultipleSizesInMemory()                .discCacheFileNameGenerator(new Md5FileNameGenerator())// 缓存数据md5加密                .build();        ImageLoader.getInstance().init(imageconfig);        //数据库初始化        DhDB db = IocContainer.getShare().get(DhDB.class);        db.init("dhdbname", Const.DATABASE_VERSION);// 初始化数据库名和版本    }}

首先重写一个Application,配置到AndroidManifest.xml

<application        android:name=".MyApplication"        ...        ></application>
public class MyApplication extends Application {    @Override    public void onCreate() {        super.onCreate();        // 调用Dhroid的初始化方法,完成注解,图片,数据库等的初始化        Dhroid.init(this);    }}

额外配置请看DemoApplication.java

新建MainActivity.java继承net.duohuo.dhroid.activity.BaseActivity
BaseActivity.java中有如下关键代码

// 内部用ArrayList控制Activity完全退出,切换到某Activity等方法private ActivityTack tack = ActivityTack.getInstanse();@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    tack.addActivity(this);}@Overridepublic void finish() {    super.finish();    tack.removeActivity(this);}@Overridepublic void setContentView(int layoutResID) {    super.setContentView(layoutResID);    if (Const.auto_inject) {        InjectUtil.inject(this);// 注解导入    }}

以后可以在这个基类中添加更多共用的代码


先来测试注解导入功能

在布局activity_main.xml中加入一个Button,在MainActivity.java中加入下面代码

@InjectView(id = R.id.button)Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    button.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Toast.makeText(MainActivity.this, "注解导入成功了,再也不用findViewById()了", Toast.LENGTH_SHORT).show();        }    });}

有些人就该问了,这个button没有初始化,直接用的话不会包空指针么?

答案是,不会。因为在声明button时在它上面加了一行注释@InjectView(id = R.id.button),这句话的意思就是将这个button指向setContentView(layoutId)中传入的布局中的id为button的节点,完成初始化。

现在把Activity中的findViewById省略了,但还是要写setOnClickListener,能不能用注解也完成呢,看下面代码

@InjectView(id = R.id.button, click = "clickBtn")Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);}public void clickBtn(View view){    Toast.makeText(MainActivity.this, "注解导入成功了, 不用写setOnClickListener了~", Toast.LENGTH_SHORT).show();}

这里要注意,方法要用public修饰,需要一个View作为参数

其他用法看这里 基础高级


再来看看网络部分

常用的有两个类DhNet.javaNetTask.java

// 这里借用知乎日报的一个接口测试一下~DhNet dhNet = new DhNet("http://news-at.zhihu.com/api/4/themes");//        dhNet.addParam("key", "value");NetTask task = new NetTask(this) {    @Override    public void doInUI(Response response, Integer transfer) {        // 请求成功        Log.d("response", response.result);    }    @Override    public void onErray(Response response) {        // 请求失败        Log.d("onErray", response.msg);    }};dhNet.doGet(task);//  dhNet.doGetInDialog(task);    //网络请求时显示一个Dialog//  dhNet.doPost(task);           //使用post请求

要注意添加权限

<!-- 网络使用权限 --><uses-permission android:name="android.permission.INTERNET" /><!-- 检查网络状态的权限 --><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

处理接口返回的数据时

@Overridepublic void doInUI(Response response, Integer transfer) {    // 请求成功    //Log.d("response", response.result);    try {        JSONObject jsonObject = new JSONObject(response.result);        JSONArray jsonArray = jsonObject.getJSONArray("others");        for (int i = 0; i < jsonArray.length(); i++) {            JSONObject other = jsonArray.getJSONObject(i);            String name = other.getString("name");            Log.d("name", name);        }    } catch (JSONException e) {        e.printStackTrace();    }}

OK,日志已经能够打出来了

12-22 18:40:11.136 11009-11009/gavinhua.demo D/name: 日常心理学12-22 18:40:11.136 11009-11009/gavinhua.demo D/name: 用户推荐日报12-22 18:40:11.136 11009-11009/gavinhua.demo D/name: 电影日报...

但是这么解析数据时不是感觉很累?
这里引入一个解析库Gson

Gson gson = new Gson();ThemeEntity themeEntity = gson.fromJson(response.result, ThemeEntity.class);Log.d("themes", themeEntity.toString());

ThemeEntity 类似根据JSON生成的POJO类,用于保存数据。

12-22 20:14:33.219 21534-21534/gavinhua.demo D/themes: ThemeEntity{limit=1000, subscribed=[], others=[OthersEntity{color=15007, thumbnail='http://pic3.zhimg. com/0e71e90fd6be47630399d63c58beebfc.jpg', description='了解自己和别人,了解彼此的...

这么简单的几行代码,就已经把数据保存好了,是一件多么快乐的事情~


接下来是持久化数据

主要分为两种:

  • SharedPreferences适用于少量的数据,例如设置类数据,用户账户信息等。接受的格式为key-value,保存格式为XML。
  • SQLiteAndroid内置的数据库,用于保存大量数据,或者不易于处理的数据。

在dhroid中提供了这两个方式的封装方法,便于开发。DhDBPerference

首先来看数据库的使用。

for (int i = 0; i < 2; i++) {    UserEntity userEntity = new UserEntity();    userEntity.setUsername("admin" + i);    userEntity.setPassword("1234");    userEntity.setSex(0);    dhDB.save(userEntity);// 增加}List<UserEntity> list = dhDB.queryAll(UserEntity.class);// 查询Log.d("list", list.toString());UserEntity admin1 = dhDB.queryFrist(UserEntity.class, "username = ?", "admin1");// 条件查询Log.d("admin1", admin1.toString());admin1.setUsername("change name");dhDB.update(admin1);// 更新list = dhDB.queryAll(UserEntity.class);Log.d("list", list.toString());dhDB.delete(admin1);// 删除list = dhDB.queryAll(UserEntity.class);Log.d("list", list.toString());
// 增加12-23 10:55:10.723 12438-12438/gavinhua.demo D/list: [UserEntity{username='admin0', password='1234', sex=0}, UserEntity{username='admin1', password='1234', sex=0}]// 条件查询12-23 10:55:10.729 12438-12438/gavinhua.demo D/admin1: UserEntity{username='admin1', password='1234', sex=0}// 修改12-23 10:55:10.756 12438-12438/gavinhua.demo D/list: [UserEntity{username='admin0', password='1234', sex=0}, UserEntity{username='change name', password='1234', sex=0}]// 删除12-23 10:55:10.775 12438-12438/gavinhua.demo D/list: [UserEntity{username='admin0', password='1234', sex=0}]

是不是很简单,但是需要配置UserEntity.java

@Entity(table = "user") // 表名public class UserEntity {    @Column(pk = true, auto = true) // 主键,自动    public long id;    @Column // 标注是要存到库中    public String username;    @Column    public String password;    @Column    public int sex;...

下面来看Perference

public class UserPerference extends Perference{    public UserEntity userEntity;// 必须用public修饰    public String type;    public boolean isActive;}
UserEntity entity = new UserEntity();entity.setUsername("admin");entity.setSex(0);entity.setPassword("123");UserPerference user = new UserPerference();user.account = "110";// 这组数据的标识user.isActive = true;user.type = "1";user.userEntity = entity;user.commit();// 提交修改UserPerference per = new UserPerference();per.load();Log.d("perference", per.toString());       

来看一下log

12-23 15:45:13.445 4508-4508/gavinhua.demo D/perference: UserPerference{userEntity=UserEntity{username='admin', password='123', sex=0}, type='1', isActive=true}

Perference的局限性很大,所以不推荐使用。


EventBus 事件总线

这个EventBus和greenrobot家的EventBus可不是一个,不要弄混了。

public static final String NAME = "clickBtn"; // 事件标识@InjectView(id = R.id.button, click = "clickBtn")Button button;@Inject // 使用这个注解,保持单例EventBus bus;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);}public void clickBtn(View view) {    bus.fireEvent(NAME);// 发送事件}@OnEvent(name = NAME) // 将这个方法与事件标识绑定public void anyWay() { //方法名随便起    Toast.makeText(MainActivity.this, "被点击了", Toast.LENGTH_SHORT).show();}@Overrideprotected void onResume() {    super.onResume();    EventInjectUtil.inject(this);// 将方法注册上}@Overrideprotected void onPause() {    super.onPause();    EventInjectUtil.unInject(this);// 反注册}

EventBus根据事件辨识去找处理事件的方法。这么一看是不是觉得没什么作用?但是它能跨Activity、Service等等处理事件呢?一下子就将模块间的通信变得简单了,降低了耦合性。

进阶用法

public void clickBtn(View view) {    bus.fireEvent(NAME, "点击按钮~");}@OnEvent(name = NAME ,onBefore = true, ui = true) // onBefore可以收到注册事件之间的消息,ui在主线程处理事件public void anyWay(String str) { // 可以根据参数对同一标识做不同处理    bus.clearEvents(NAME); // 取消事件向下传递    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();}@OnEvent(name = NAME)public void anyWay() {    Toast.makeText(MainActivity.this, "被点击了", Toast.LENGTH_SHORT).show();}

更多进阶用法看 这里


总结

dhroid框架已经有点过时了,比如网络部分不能加header、不支持gzip、要求权限过多、不支持Android M的新的权限模型等等。
但是还是有值得学习的地方。更多的文档看 这里

0 0
原创粉丝点击