概述:

阅读优秀的开源项目:NBAPlus

一、应用启动分析:

  • 1、初始化LeakCanary进行内存泄露检测

  • 2、AppService类的初始化

AppService类:此类将常用的全局对象进行统一的封装管理,避免了Application的臃肿。

  • 1、常用全局对象的初始化

  • 2、Subscription的管理,避免内存泄露(CompositeSubscription)

  • 3、初始化了一个后台线程对数据库操作对象API请求对象进行初始化(为了启动效率问题吗?)

二、基类的封装:

1、BaseActivity

  • ButterKnife的绑定
  • EventBus的注册
  • CompositeSubscription的添加
  • onDestory方法中反注册与remove

2、BaseFragment

  • ButterKnife的绑定
  • EventBus的注册及反注册

三、MainActivity分析:

  • 1、进行Drawer的初始化
  • 2、EventBus的onEventMainThread()方法
  • 3、默认初始化“新闻”Fragment

四、网络请求分析:

  • 0、声明NbaplusAPI和NewsDetileAPI请求接口
  • 1、NbaplusFactory生产NbaplusAPI和NewsDetileAPI两个接口对象
  • 2、以上两个对象在NbaplusClient中通过Retrofit构建。

五、rxmethod包

对数据的操作方法,发起网络请求,并回调EventBus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static Subscription getTeams(String date) {

Subscription subscription = AppService.getNbaplus().getGames(date)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Games>() {
@Override
public void call(Games games) {//成功的回调
AppService.getBus().post(new GamesEvent(games, Constant.Result.SUCCESS));
}
}, new Action1<Throwable>() {//失败的回调
@Override
public void call(Throwable throwable) {
AppService.getBus().post(new GamesEvent(null, Constant.Result.FAIL));
}
});
return subscription;
}

六、数据的缓存使用greenDAO:

详细用法:

http://www.open-open.com/lib/view/open1438065400878.html

那些经典的写法:

在阅读代码的时候看到了一些不错的可以借鉴的写法:

1、虽然有butterknift可以不用写findViewById但这样一个‘ $ ‘符号搞定也是一种不错的选择。

1
2
3
private <T extends View> T $(@IdRes int id) {
return (T) findViewById(id);
}

概述:

本文对这里的UML教程进行整理,便于自己阅读。

一、类与类之间的关系:

1、关联关系:

图:

http://7xqumq.com1.z0.glb.clouddn.com/duwei_contains.png

代码:

1
2
3
4
5
6
7
8
public class LoginForm {  
private JButton loginButton; //定义为成员变量
……
}

public class JButton {
……
}

关联关系的分类:(略过暂不学)

  • 双向关联
  • 单向关联
  • 自关联
  • 多重性关联
  • 聚合关系
  • 组合关系

2、依赖关系:

图:

http://7xqumq.com1.z0.glb.clouddn.com/duwei_dependency.png

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Driver {  
public void drive(Car car) {
car.move();
}
……
}

public class Car {
public void move() {
......
}
……
}

3、泛化关系(继承关系):

图:

http://7xqumq.com1.z0.glb.clouddn.com/duwei_generalization.png

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//父类  
public class Person {
protected String name;
protected int age;

public void move() {
……
}

public void say() {
……
}
}

//子类
public class Student extends Person {
private String studentNo;

public void study() {
……
}
}

//子类
public class Teacher extends Person {
private String teacherNo;

public void teach() {
……
}
}

4、接口与实现关系:

图:

http://7xqumq.com1.z0.glb.clouddn.com/duwei_implement.png

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface Vehicle {  
public void move();
}

public class Ship implements Vehicle {
public void move() {
……
}
}

public class Car implements Vehicle {
public void move() {
……
}
}

概述:

本文记录:

  • Comparable接口的介绍和使用
  • Comparator接口的介绍和使用
  • 两个接口的比较

一、Comparable接口的介绍和使用

1、基本介绍

JAVA中基本数据类型(int)等可以进行比较和排序,那么对象数据类型是否可以进行排序呢?答案是肯定的。

  • Comparable接口可以强行对实现它的 每个类的对象进行整体排序。
  • 实现此接口的对象列表(和数组)可以通过 Collections.sort (和 Arrays.sort )进行自动排序。
  • 实现此接口的类需要复写compareTo()方法。

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Person implements Comparable<Person>{//实现接口	
int age;
String name;

public Person(int age,String name){
this.age = age;
this.name = name;
}
//getter&setters

@Override //如果前者大于后者,返回1,等于返回0,小于返回-1
public int compareTo(Person person) {//复写方法
if(this.age<person.age)
return -1;
else if(this.age==person.age)
return 0;
else return 1;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//测试代码
public class TestComparable {

public static void main(String[] args) {
List<Person> person = new ArrayList<Person>();

person.add(new Person(15,"xiaoming"));
person.add(new Person(20,"xiaoli"));
person.add(new Person(18,"xiaowang"));
Collections.sort(person);
for (Person person2 : person) {
System.out.println(person2.getAge());
}
}

}

二、Comparator接口的介绍和使用

例:Comparator实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14

public class MyComparable implements Comparator<Person>{

@Override
public int compare(Person person1, Person person2) {

if(person1.age<person2.age)
return -1;
else if(person1.age == person2.age)
return 0;
else return 1;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TestComparator {
public static void main(String[] args) {
List<Person> person = new ArrayList<Person>();
MyComparable c= new MyComparable();
person.add(new Person(15,"xiaoming"));
person.add(new Person(20,"xiaoli"));
person.add(new Person(18,"xiaowang"));
person.add(new Person(27,"xiaoma"));
Collections.sort(person,c);
for (Person person2 : person) {
System.out.println(person2.getAge());
}
}

}

三、两个接口的比较

  • Comparator位于包java.util下,而Comparable位于包java.lang下
  • Comparable定义在模型的内部,而Comparator实现在模型外部
  • Comparable覆盖compareTo()方法,Comparator覆盖compare()方法

概述:

本文记录:

  • ViewDragHelper的基本介绍和使用(初稿)

1、What is ViewDragHelper ?

ViewDragHelper is a utility class for writing custom ViewGroups. It offers a number of useful operations and state tracking for allowing a user to drag and reposition views within their parent ViewGroup.

ViewDragHelper是一个写自定义ViewGroup的工具类,它提供了一些有用的操作和状态跟踪来让用户对View在其父容器中进行拖拽和重新摆放。

2、How to create it ?

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Factory method to create a new ViewDragHelper.//工厂方法创建一个ViewDragHelper
*
* @param forParent Parent view to monitor
* @param sensitivity Multiplier for how sensitive the helper should be about detecting the start of a drag. Larger values are more sensitive. 1.0f is normal.
* @param cb Callback to provide information and receive events//一个提供信息和接收事件的回调
* @return a new ViewDragHelper instance
*/

public static ViewDragHelper create(ViewGroup forParent, float sensitivity, Callback cb) {
final ViewDragHelper helper = create(forParent, cb);
helper.mTouchSlop = (int) (helper.mTouchSlop * (1 / sensitivity));
return helper;
}

3、Important Callback

http://7xqumq.com1.z0.glb.clouddn.com/duwei_viewdraghelper.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

/**
* Called when the user's input indicates that they want to capture the given child view
* with the pointer indicated by pointerId. The callback should return true if the user
* is permitted to drag the given view with the indicated pointer.
*
* <p>ViewDragHelper may call this method multiple times for the same view even if
* the view is already captured; this indicates that a new pointer is trying to take
* control of the view.</p>
*
* <p>If this method returns true, a call to {@link #onViewCaptured(android.view.View, int)}
* will follow if the capture is successful.</p>
*
* @param child Child the user is attempting to capture
* @param pointerId ID of the pointer attempting the capture
* @return true if capture should be allowed, false otherwise
*/

public abstract boolean tryCaptureView(View child, int pointerId);
1
2
3
4
5
6
7
8
9
10
11
/**
* 约束被拖拽的子View沿着X轴移动,默认的实现不允许水平移动 ,子类必须覆盖这个方法并提供想要的 clamping.
*
* @param child Child view being dragged
* @param left Attempted motion along the X axis
* @param dx Proposed change in position for left
* @return The new clamped position for left
*/

public int clampViewPositionHorizontal(View child, int left, int dx) {
return 0;
}