Android进阶知识点

四大组件的生命周期

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的生命周期

fragment:

onAttach onCreate onCreateView onActivityCreate onstart onResume

onPause onStop OnDestroyView onDestroy onDetach

 

 

activity的启动模式和使用场景

使用:在ManiFest.xml文件,activity 标签中使用。例如 android:launchMode=""

standard

此模式是默认模式,activity会一个个往上叠。

singleTop

如果启动的是和当前一样(栈顶)的activity就回调onNewIntent()方法,避免重复创建。

场景:登录成功,点击推送跳转到目前已打开的activity,servicey收到信息,需要返回到界面。

singleTask taskAffinity

如果启动的actiivity已经在栈中,就重用,不创建,就回调onNewIntent()方法,并且将这个activity以上的activity全出出栈。

taskAffinity用来指定要将次activity放入的栈的名字,默认是包名

场景:游览器界面等

singleInstance

单实例模式,为启动的actiivity单独创建一个activity 栈,具有全局重用性。

 

 

context

定义:

系统角度理解:他是一个场景,代表与操作系统交互的一种过程。

Context 是一个抽象类 Activity Service Application 是他的子类。

如何获取:

View.getContext

Activity.getApplicationContext(),全局主进程Context

ContextWrapper.getBaseContext 不建议使用

this 返回当前实例

Context引发内存泄漏:

不要让长于Activity的对象持有到Activity的引用

经量使用Application的Context

经量不要在Activity中使用非静态内部类,应为非静态内部类会隐式持有外部类实例的引用

 

 

android 跨进程

多进程造成麻烦:

静态成员完全失效

线程同步失效

SharedPreferences可靠性降低

Application多次创建

方式:

binder:客户端和服务端通信的媒介

bundle

ContentProvider

Messenger

AIDL

文件共享

Socket

 

 

进程保活

两个方向

提高进程优先级 service.startForeground()

进程被杀死之后能够唤醒 onStartCommand return START_STICKY;

 

 

RecyclerView 和 ListView 的区别

ListView:

1. 继承重写BaseAdapter类;

2. 自定义ViewHolder与convertView的优化(判断是否为null);

public class LvAdapter extends BaseAdapter {

    private List<String> datas;
    private Context context;

    public LvAdapter(List<String> 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<RvAdapter.ViewHolder> {

    private List<String> datas;
    private Context context;

    public RvAdapter(List<String> 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 window view

Activity在onCreate之前调用attach方法,在attach方法中会创建window对象。window对象创建时并木有创建DecorView对象。用户在Activity中调用setContentView,然后调用window setContentView,这时会检查DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的View 添加到DecorView中。

 

 

android 的事件分发机制,滑动冲突

事件分发一开始总是由外向内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 不拦截,否则事件就全部交由父容器处理了

 

内部拦截法

父容器不做拦截处理,所有的事件都交给子元素,如果子元素需要此事件则消耗,不需要则交由父容器处理。

 

 

handler 的原理

一般用于子线程更新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去发送消息

 

以上内容,未完待补充

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值