1.单例模式
https://www.cnblogs.com/Ycheng/p/7197751.html
作用:保证在Java应用程序中,一个类class只有一个实例存在;而且可以节省内存,因为它限制了实例的个数,有利于垃圾回收
1.饿汉模式
一开始的时候就进行了实例化,无论你到底用到与否,在类加载的时候就立即创建对象

【注意:】与 “懒加载”进行类比
private static TaskGoApplication instance;
2.懒汉模式
等到需要使用的时候才进行创建
3.弊端--进程同步Bug-synchronized同步锁
一个单例模式创建的对象是可以同时被多个线程处理的,如果一个对象被多个线程同时处理的话,就有可能出现线程同步问题。
解决方法:synchronized 同步锁
http://blog.51cto.com/lavasoft/99155
2.“确认”Button 界面中靠右且有一定距离
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="11dp"
3.文字覆盖于按钮之下

在位置布局上进行设置

4.让一段文字竖直方向上居中,使用gravity 而不是用layout_gravity
android:gravity="center_vertical"
5.一个有生命的列表
以Information通知界面为例
1.InformationFragmrnt
public class InformFragment
extends BasePresenterFragment
implements InformationItemListener, SwipeRefreshLayout.OnRefreshListener
自动重写下面这些方法
/**
* SwipeRefreshLayout接口中的方法
*/
@Override
public void onRefresh() {
}
/**
* InforItemListener接口中的方法
*点击用户头像显示用户详细信息,点击确认按钮触发其他事件
* @param position
*/
@Override
public void onClickPicture(int position) {
}
@Override
public void onClickSure(int position) {
}
@Override
protected BaseContract.Presenter initPresenter() {
return null;
}
/**
* BasePresenterFragment中的方法
*
* @return
*/
@Override
protected int getLayoutId() {
return R.layout.fragment_information;
}
@Override
protected void initVariable() {
}
@Override
protected void initView() {
}
@Override
protected void loadData() {
}
/**
* generate-Bind自动建立的方法
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO: inflate a fragment view
View rootView = super.onCreateView(inflater, container, savedInstanceState);
unbinder = ButterKnife.bind(this, rootView);
return rootView;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
2.InformationItemListener
public interface InformationItemListener {
/**
* 点击头像事件
* @param position
*/
void onClickPicture(int position);
/**
* 点击确认按钮事件
* @param position
*/
void onClickSure(int position);
}
3.R.layout.fragment_information

4.InformationModel
public class InformationModel {
public InformationModel(String pictureUrl,String receiveName,String releaseName){
this.pictureUrl=pictureUrl;
this.receiveName=receiveName;
this.releaseName=releaseName;
}
/**
* 头像相关
*/
private String pictureUrl;
public String getPictureUrl() {
return pictureUrl;
}
public void setPictureUrl(String pictureUrl) {
this.pictureUrl = pictureUrl;
}
/**
* 送货人相关
* @return
*/
public String getReceiveName() {
return receiveName;
}
public void setReceiveName(String receiveName) {
this.receiveName = receiveName;
}
private String receiveName;
/**
* 发布者相关
* @return
*/
public String getReleaseName() {
return releaseName;
}
public void setReleaseName(String releaseName) {
this.releaseName = releaseName;
}
private String releaseName;
}
5.InformationListRecAdapter
自动响应:
public class InformationListRecAdapter extends BaseRecyclerViewAdapter<InformationModel> {
public InformationListRecAdapter(Context context, List<InformationModel> informationModels) {
super(context, informationModels);
}
@Override
public BaseViewHolder<InformationModel> onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
}
补充:内部类ItemHolder
class ItemHolder extends BaseViewHolder<InformationModel> implements View.OnClickListener
6.多线程
Java中实现多线程有两种途径:继承Thread类活着实现Runnable接口
1.Thread
使用Thread的时候只需要new一个实力出来,调用start()方法即可以启动一个线程
Thread Test = new Thread();
Test.start();
2.Runnable
使用Runnable的时候需要先new一个继承Runnable的实例,之后用子类Thread调用
Test impelements Runnable
Test t = new Test();
Thread test = new Thread(t);
使用Runnable定义的子类中没有start()方法,只有Thread类中才有
3. 例题
需要分别打印出a与b各10次,并且每打印一次a睡1秒,打印一次b睡2秒。 可以在run方法外面定义String word与int time. 之后用
Thread t1 = new Thread();
Thread t2 = new Thread();
t1.word = "a"
t1.time = 1000
t2.Word = "b"
t2.time = 2000
t1.start();
t2.start();
此处需要注意⚠️新建一个project用于测试Runnable不是一个简单的Java编译器,你需要让这个inflater能够找到启动哪一个具体的Activity,而不是自己zz的取名一个“MainActivity”的类......呵呵呵-----所以需要 把之前想要实现的main里面的方法,转换为一个OnCreat()里面的一个 initXXX


7.实现点击确认按钮病吧这条item删除,然后获取相对应的id
还是以通知界面为例子
1.InformFragment.java实现InformationItemListener.java自动@Override里的方法
public class InformFragment implements InformationItemListener{....}

2.InformationItemListener.java-监听器,监听事件的发生

3.InformationListRecAdapter-适配器,ItemHolder在此定义-在此一定将每一条item的position进行设置,对,源头就在这里,然后重返Fragment中的点击函数里面,将 会发生的事情写进去
8.对输入的密码进行隐藏设置
android:inputType="textPassword"


9.设置按钮的可点击事件
mbtnLogin.setClickable(true);
10.onLoginFailed(...)与onWriteFailed(...)
登录界面关于View的接口回调方法需注意:“输入密码错误“与”输入格式不正确“is different
- 输入的格式不正确:是指在Presenter验证数据是否正确的isDataTrue()里关于输入的账号为空、正则表达式要起u、密码长度限制:过长或者过短 的判断
- 输入密码错误:是指 经过网络请求过后 账号密码核对后有差异
因为我们想要区分这两种状态,是因为如果输入的账号正确,但是密码错误,当我们再次输入正确密码的时候,“登录”按钮变成了不可点击的状态,即使密码正确仍旧进入不了主界面
(因为isDatatrue判断的是没问题的,满足了账号密码的位数,也满足了正则表达式子,button的点击设置回不去true,所以我们还需要onLoginFailed(...)方法重新将mbtnLogin.setClickable(true);)

11.解决同时同步多个线程
针对重复多次快速点登录按钮出现重复出现进入MainActivity界面的问题学习
大体上的思路👇:

异步线程和UI线程
凡是在这里面写的都是同步异步线程👇:

能看到的都是UI线程,比如点击一个 button实现界面Activity之间的跳转......




12.在Presenter数据交换的过程中除了success方法还需要的fail方法在哪?
宏宇封装的底层中是👇这样:

接下来我们在接口中这样使用
但注意⚠️,逻辑方面的考虑决定了我们把方法放在底层的Override中实现

13.Call与Observable
注释部分是用RxJava,未注释部分是用原始的网络请求


【小注意⚠️】

