activity:
onCreate onStart onResume onPause onStop onDestroy
onRestart 回到桌面再切回来,跳转到另一个activity再返回 ,本应用切换到另一个应用再切换回来时调用
service:
onCreate onStartCommond onDestroy
onCreate onBind onUnBind onDestroy
BroadcastReceiver:
onReceive 动态注册时一定要解注册,静态注册时默认自动解
ContentProvider:
ContentProvider是一个抽象类,如果我们要开发自己的内容提供者就需要继承它并重写一下方法
onCreate query insert delete update getType(用于返回指定的Uri中的数据MIME类型)
fragment:
onAttach onCreate onCreateView onActivityCreate onstart onResume
onPause onStop OnDestroyView onDestroy onDetach
使用:在ManiFest.xml文件,activity 标签中使用。例如 android:launchMode=""
standard
此模式是默认模式,activity会一个个往上叠。
singleTop
如果启动的是和当前一样(栈顶)的activity就回调onNewIntent()方法,避免重复创建。
场景:登录成功,点击推送跳转到目前已打开的activity,servicey收到信息,需要返回到界面。
singleTask taskAffinity
如果启动的actiivity已经在栈中,就重用,不创建,就回调onNewIntent()方法,并且将这个activity以上的activity全出出栈。
taskAffinity用来指定要将次activity放入的栈的名字,默认是包名
场景:游览器界面等
singleInstance
单实例模式,为启动的actiivity单独创建一个activity 栈,具有全局重用性。
定义:
系统角度理解:他是一个场景,代表与操作系统交互的一种过程。
Context 是一个抽象类 Activity Service Application 是他的子类。
如何获取:
View.getContext
Activity.getApplicationContext(),全局主进程Context
ContextWrapper.getBaseContext 不建议使用
this 返回当前实例
Context引发内存泄漏:
不要让长于Activity的对象持有到Activity的引用
经量使用Application的Context
经量不要在Activity中使用非静态内部类,应为非静态内部类会隐式持有外部类实例的引用
多进程造成麻烦:
静态成员完全失效
线程同步失效
SharedPreferences可靠性降低
Application多次创建
方式:
binder:客户端和服务端通信的媒介
bundle
ContentProvider
Messenger
AIDL
文件共享
Socket
两个方向
提高进程优先级 service.startForeground()
进程被杀死之后能够唤醒 onStartCommand return START_STICKY;
ListView:
1. 继承重写BaseAdapter类;
2. 自定义ViewHolder与convertView的优化(判断是否为null);
public class LvAdapter extends BaseAdapter {
private List datas;
private Context context;
public LvAdapter(List datas, Context context) {
this.datas = datas;
this.context = context;
}
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int i) {
return datas.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item,viewGroup,false);
viewHolder = new ViewHolder();
viewHolder.tv1 = convertView.findViewById(R.id.tv1);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv1.setText(datas.get(i));
return convertView;
}
class ViewHolder {
TextView tv1;
}
}
RecyclerView:
1. 继承重写RecyclerView.Adapter与RecyclerView.ViewHolder
2. 设置LayoutManager,以及layout的布局效果
public class RvAdapter extends RecyclerView.Adapter {
private List datas;
private Context context;
public RvAdapter(List datas, Context context) {
this.datas = datas;
this.context = context;
}
class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.tv1)
TextView tv1;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item, parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.tv1.setText(datas.get(position));
}
@Override
public int getItemCount() {
return datas.size();
}
}
区别
1. viewHolder的定义不同,ListView需要自己定义,RecyclerView是规范好的。
2. 复用不同,ListView是需要手动setTaggetTag,RecyclerView 是全部自己搞定。
3. RecyclerView多了一些LayoutManager工作,但是实现了布局多样化。
4. ListVIew可以添加头尾布局,addHeaderView addFooterView,但是RecyclerView只能去根据ViewHolder的type来实现。但是这回影响到Adapter的数据。需要手动处理。
5. 刷新 ListView使用notifyDataSetChanged() 全局刷新 RecyclerView 可以实现局部刷新例如
notifyItemChanged()。
6. 点击事件ListView有item点击事件,RecyclerView需要通过接口回调。
7. 实现嵌套滚动机制,RecyclerView实现了,ListView没有实现。
Activity在onCreate之前调用attach方法,在attach方法中会创建window对象。window对象创建时并木有创建DecorView对象。用户在Activity中调用setContentView,然后调用window setContentView,这时会检查DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的View 添加到DecorView中。
事件分发一开始总是由外向内activity->window->view
事件分发的三个重要方法
1. public boolean dispatchTouchEvent(MotionEvent event)
分发的方法,如果当前view能接收到事件,那么此方法必定调用,返回结果受到onTouchEvent 和 子View的dispatchTouchEvent影响,表示是否消耗此事件。
2. public boolean onInterceptTouchEvent(MotionEvent event)
在dispatchTouchEvent中调用,返回结果表示当前view是否拦截事件。viewgroup默认返回false,不拦截。view 没有此方法,所以一旦有事件传递给他,那么他就一定会去执行onTouchEvent。
3. public boolean onTouchEvent(MotionEvent event)
在dispatchTouchEvent中当onInterceptTouchEvent返回的是true时(要拦截)调用,返回结果表示是否消耗此事件,默认返回true,除非这个view的clickable 是false不可点击的。并且还有一个属性longClickable 也为false,这个属性默认为false。
onTouch->onTouchEvent->onClick
onTouch 如果消耗了此事件,返回为true则不会继续执行onTouchEvent。
如果我们有设置onClickListener 那么onClick会被调用,他优先级最低
滑动冲突
不同向滑动冲突
同向滑动冲突
两者混合使用冲突
外部拦截法
重写父容器的onInterceptTouchEvent()根据要求返回true|false来控制
ACTION_DOWN 必须返回false 不拦截,否则事件就全部交由父容器处理了
内部拦截法
父容器不做拦截处理,所有的事件都交给子元素,如果子元素需要此事件则消耗,不需要则交由父容器处理。
一般用于子线程更新UI
//在主线程使用
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e(TAG,"------------> msg.what = " + msg.what);
}
};
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(5000);
mHandler.sendEmptyMessage(0);
}
}).start();
//在子线程使用
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(5000);
//调用Looper.prepare()方法
Looper.prepare();
mHandlerThread = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
mHandlerThread.sendEmptyMessage(1);
//调用Looper.loop()方法
Looper.loop();
}
}).start();
//主线程已经是可用的 Looper.prepareMainLooper();
Handler的消息处理主要有五个部分Message Handler MessageQueue Looper ThreadLocal
Message字面意思就是消息,常用字段what 、arg1 、arg2,携带整型数据,obj可以携带Object对象
Handler主要用于发送和处理消息
MessageQueue消息队列(单链表),每一个线程只有一个消息队列,用于存放Handler发送的消息,等待处理
Looper每一个线程只有一个Looper,用于循环发现是否有新消息,如果有,就交由Handler处理
ThreadLocal他是一个线程内部存储类,用来保证 MessageQueue和Looper在一个线程只有一个对象
View的postDelayd Activity的runOnUiThread 最终都是调用Handler去发送消息
以上内容,未完待补充