Android 框架整合

https://admin@localhost:8443/r/liuyuan.gitGIT工具使用

1、服务器搭建(截图见PPT)

2、客户端安装及使用

3、常见操作

4、注意事项:

a)链接的处理https://admin@localhost:8443/r/takeout.git

1、admin@删除

2、localhost换成ip地址

b)由于服务器存在安全证书


客户端如果想要链接上必须对此问题进行处理,即不做安全校验

Cmd中输入命令:git config --global --bool --add http.sslVerify false

c)工程提交时需要设置忽略文档信息(原则:在本地能够生产的文件都不需要提交)

d)代码更新时需要先从服务器获取最新的更新,然后拉取代码。

e)

MVC转换到MVP

MVC模式

M:model

V:view

C:controller

在Android中默认按MVC的方式构建项目,V—layout,C—Activity。

登陆案例代码分析。

MVP模式

M:model

V:view

P:presenter

我们这里把与业务有关的代码都放到了P中。

解耦和方式

1、利用配置文件,使用反射获取到需要加载的对象。

2、设计模式:单例、工厂、观察者……

Dagger2

Dagger2简介

1、什么是Dagger2?

Dagger是为Android和Java平台提供的在编译时进行依赖注入的框架。

编译时:编辑时生成代码(rebulid),我们完成所需对象的注入。(假设使用反射,应该是什么时候起作用?)。

2、为什么使用Dagger2?

Dagger2解决了基于反射带来的开发和性能上的问题。

3、做什么工作?

本项目中Dagger2主要用于做界面和业务之间的隔离。

使用手册

一、引入配置

1、添加dagger2的依赖

compile 'com.google.dagger:dagger:2.6'

2、编译时生成代码的插件配置(android-apt)

a)project的gradle中添加

buildscript {

dependencies {

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

}

}

b)apt插件的使用

modle的gradle中添加

apply plugin: 'com.neenbedankt.android-apt'

c)关联Dagger2

dependencies {

apt 'com.google.dagger:dagger-compiler:2.6'

}

二、操作步骤(熟练掌握)、


三、深入解析(了解)

在操作中会使用到@Inject、@Module、@Provides、@Conponent注解,那么他们分别在完成什么工作?

MainActivityPresenter presenter=new MainActivityPresenter(this);

@Inject                          @Conponent          @Module  @Provides

MainActivity_MembersInjector

public voidinjectMembers(MainActivity instance) {

if(instance ==null) {

……}

instance.presenter=presenterProvider.get();

}

其实,Dagger2在使用这几个注解解决三个问题。

1.创建对象的代码放到那里去了?

2.创建好的对象给谁(指定接收者)?

3.如何将创建好的对象赋值给接收者?

l指定创建对象的类(组件)和方法

@Module:指定创建对象的类

@Provides:指定创建对象的方法

初始时:

publicclass MainActivityModule {

public String createString(){

return new String(“liutao”);

}

}

添加注解后:

@Moudle

publicclass MainActivityModule {

@Provides

public String createString(){

return new String(“liutao”);

}

}

l指定接收者

创建好的对象需要赋值给指定的目标,我们需要通过@Inject注解告知Dagger2容器,把已经创建好的对象赋值给谁。

public class MainActivity…..{

@Inject

String target;

}

l将接收者和创建好的对象联系在一起

通过@Component来指定工作由哪个接口完成,通过这个接口我们可以看到组件和接收者。

ButterKnife工具使用

配置依赖:compile 'com.jakewharton:butterknife:5.1.1'

安装插件:在plugins中搜索butterknife,安装Android ButterKnife Zelezny

控件初始化操作:



 

Retorfit

一、Retorfit简介

Retorfit是一个功能强大的联网工具。可以看成是OKHttp+数据解析(json、xml等)的组合。

说明文档:http://square.github.io/retrofit/

GitHub:https://github.com/square/retrofit

二、使用手册

1.引入配置

l添加Retrofit依赖:

compile'com.squareup.retrofit2:retrofit:2.1.0'

l使用Gson进行数据解析

compile'com.google.code.gson:gson:2.2.4'

l将Retorfit与Gson关联

compile'com.squareup.retrofit2:converter-gson:2.1.0'

2.使用步骤

1)创建Retorfit.Builder对象,通过Builder指定基本配置信息。

Retrofit.Builder builder = new Retrofit.Builder();

builder.baseUrl("http://localhost:8080/");

builder.addConverterFactory(GsonConverterFactory.create());

2)通过Builder构建Retorfit对象

Retrofitretrofit= builder.build();

3)配置链接和参数

public interface ResponseInfoAPI {

@GET("TakeoutService/login")

Call login(@Query("username") String username,@Query("password") String password);

}

注:ResponseInfo是服务器回复数据封装成的对象。

测试链接http://localhost:8080/TakeoutService/login?username="liutao"&password="bj"

4)完整链接组合

ResponseInfoAPI api = retrofit.create(ResponseInfoAPI.class);

5)执行联网操作

Call call =api.login(“itliutao”,”bj”);

call.enqueue(new Callback() {

@Override

public void onResponse(Response response, Retrofit retrofit) {

//结果处理

}

@Override

public void onFailure(Throwable throwable) {

//异常处理

}

});

请求方法:@GET / @POST

URL处理:测试链接http://localhost:8080/TakeoutService/login?username="liutao"&password="bj"

替换原则:

1、@Path -替换参数

@GET("/group/{id}/users")

public Call> groupList(@Path("id") int groupId);

2、@Query -添加查询参数

@GET("/group/{id}/users")

public Call> groupList(@Path("id") int groupId, @Query("sort") String sort);

3、@QueryMap -如果有多个查询参数,把它们放在Map中

@GET("/group/{id}/users")

public Call> groupList(@Path("id") int groupId, @QueryMap Map options);

Ormlite工具使用

配置

compile'com.j256.ormlite:ormlite-android:5.0'

使用

常用注解

@DatabaseTable(tableName = "t_user")

指定实体和表的一一对应关系

@DatabaseField()

指定属性与表中列的一一对应关系

常用配置说明:

主键:id = true

自增主键:generatedId = true

列名:columnName = "name"

是否为空:canBeNull =true

外键:foreign =true

示例:

@DatabaseTable(tableName ="t_address")

public classAddressBean {

@DatabaseField(id =true)

private int_id;

@DatabaseField(canBeNull =false)

privateStringgoodsAddress;

@DatabaseField(canBeNull =false)

privateStringvillage;

@DatabaseField(canBeNull =false,foreign =true,columnName ="user_id",foreignColumnName ="_id")

privateUserBeanuser;

}

@DatabaseTable(tableName ="t_user")

public classUserBean {

@DatabaseField(id =true)

private int_id;

@ForeignCollectionField(eager =true)

privateForeignCollectionaddressList;

}

DBHelper管理

与原声的DBHelper相同,主要负责数据库的创建和表的维护。需要继承OrmLiteSqliteOpenHelper类。

使用工具:TableUtils完成表的相关操作,如创建、清空、删除

项目整合

包结构划分。项目比较复杂时,大家开始动手完成代码前必须要想清除,代码是放在哪里的。


业务层联网操作

依据接口文档中给出的服务器回复信息,设置Retorfit。由于服务器回复的是Json文件,并且服务器地址一般情况下不会变动,所以Retorfit的创建可以在业务层基类中完成

newRetrofit.Builder().

baseUrl(Constant.HOME).

addConverterFactory(GsonConverterFactory.create()).

build();

从接口文档中我们知道,回复的数据格式是统一的,我们仅仅封装一个对象就可以满足访问网络的需求


与之对应的API接口设置一个就能满足需求。


不同的模块在处理时只需要增加对应的方法即可,方法返回的类型是相同的。所以我们自需要创建ResponseInfoAPI的实现类对象就能满足需求。

ResponseInfoAPI responseInfoAPI =retrofit.create(ResponseInfoAPI.class);

可以集成到业务的基类中。

联网回复结果处理

当获取到服务器返回数据后会出发设置好的Callback,两个方法如下:

public voidonResponse(Call call, Response response)

public void onFailure(Call call, Throwable t)

我们需要对回复的结果做进一步处理,首先必须要判断code值,如果为0表示当前请求操作服务器处理成功,返回用户想要数据,如果不为0表示服务器处理该请求出现问题,比如:用户名或密码输入错误。这个信息我们需要统一展示给用户。所以我们需要对两个方法进行统一处理。在onResponse中需要

ResponseInfo body = response.body();

if("0".equals(body.getCode())) {

// 服务器处理成功,可以解析data数据了parseDestInfo(body.getData());

}else{

String error=errorInfo.get(body.getCode());

onFailure(call,newRuntimeException(error));

}

如果出现服务器处理错误会出发onFailure方法,同时由于网络问题也会触发该方法,我们需要对出发来源进行区分,可以定义一个自己的异常,封装服务器返回错误提示信息,展示给用户,如果是网络问题则提示:请检查网络,或服务器忙等。代码如下(这里使用了RuntimeException)

public void onFailure(Call call, Throwable t) {

if(t instanceof RuntimeException){

showError(((RuntimeException)t).getMessage());

}

showError("服务器忙,请稍后重试……");

}

业务层数据库操作

数据库需要使用到DBHelper,所以我们在DBHelper类中实现了单例,这样就不用每次都创建了。

需要重点注意的问题,操作DBHelper时需要传递上下文,我们需要使用生命周期较长的Application作为参数,不能使用某个具体的Activity或Fragment对象。

公共布局处理

首先完成MainActivity,布局比较简单,我们经常实现,所以layout大家可以直接拷贝了。

问题是:很多项目中都会有这种需求,但Item的数量不等,我们不得不调整代码,有通用的实现方式吗?

注意我们Layou的底部导航部分内容。


这样进行布局的目的是我们刻意批量的处理各种事件。

比如:底部导航每个Item都有自己的点击事件,那么我们只需要获取到底部导航容器,对他的孩子(不包含孙子),循环一次就可以设置好点击事件。代码如下:

intchildCount =switcherContainer.getChildCount();

for(inti =0; i < childCount; i++) {

switcherContainer.getChildAt(i).setOnClickListener(switherOcl);

}

在某个孩子被点击后我们可以处理以下工作:

1、修改对应状态,达到切换图片背景和文字颜色的效果

2、切换Fragment,我们可以把用到Fragment按顺序添加到集合中,当点击某个按钮后,会获取到期再底部容器中的具体位置信息,位置从0开始,而Fragment集合也是从0开始基数,所以他们的位置是一一对应的。

这里边有一个让人非常恼火的问题,每个Item都有两张不同的图片,我们需要逐个完成选择器的编写,这里面给大家介绍一个插件,他可以帮助我们生产这部分代码,只要你每组图片的命名按照其规定要求就能够帮助我们生产选择器。


命名规则可以查询提供的官方文档。

操作截图:




Fragment切换

将每个底部容器Item对应的Fragment放到一个容器中,注意Fragment的添加顺序,需要与Item的顺序保持一致,然后我们就可以通过Item的index找到对应的Fragment进行切换了。

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

推荐阅读更多精彩内容