Android的一些知识点

Android

Activity
  • Activity 生命周期
    正常:
    onCreate -> onStart -> onResume -> runing -> onPause -> onStop -> onDestory

    异常终止:
    调用onSavaInstanceState -> onRestoreInstanceState
        (onStop 之前调用)         (onStart之后调用)

    Activity重新创建 设置configChanges可避免重新创建
  • Activity 启动模式
    LaunchMode : standand singleTop singleTask singleInstance

standand : 启动后Activity 默认进入启动他的Activity的任务栈,非Activity context 启动Activity时会报错,因为没有任务栈。需要指定FLAG_ACTIVITY_NEW_TASK 标记位置。实际上是以singleTask启动的。

singleTop : 位于栈顶不会重新创建,会调用onNewIntent方法。

singleTask : 位于栈中就不会重新创建,会调用onNewIntent方法。

singleInstance : 只能单独的位于一个栈中
两种设置方式:
launchMode指定, intent.addFlags

  • Android 多进程
    通过android:process指定, 通过调用fork()

Android为每个进程都分配一个独立的虚拟机

Serializable 接口 serialVersionUID
Parcelable 接口

Andriod 进程间通信

Binder Bundle 文件共享 AIDL Messenger ContentProvider Socket

Binder 机制:
主要是client-server机制,底层有ServiceManager 负责管理所有的service,所有的service都需要在ServiceManager中注册,之后client才能在ServiceManager中得到service的引用。client请求service的服务或数据,先在ServiceManager中查询,获取service的binder的引用,调用所需要的方法。由于service 中的binder方法和client中的binder方法是一一对应的,client调用方法时会发送指定方法的标示,service根据方法的标志识别调用哪个方法,此时client端是阻塞的。等待service端方法执行完成后,返回结果,client继续执行。相当于client拥有service的一个引用。

service向ServiceManager注册的时候也需要进程间通信,所以ServiceManager在初始化的时候指定自己的标志为0,service通过0来获取ServiceManager的引用,与其通信,此时service扮演的角色是client。

Andriod View
  • view的坐标 是相对与父容器来说的,是相对坐标
  • view 平移过程中,top left值不变,表示的是原始位置信息,改变的是x,y,translationX,translationY的值
  • view 滑动三种方法:1.scrollTo/scrollBy 2.属性动画 3.修改layoutParams
  • Scroller原理: 不断让view重绘,不断调用view的computeScroll方法。
  • view 事件分发 : 对MotionEvent事件的分发
    dispathTouchEvent
    onInterceptTouchEvent
    onTouchEvent

onTouchListener
onClickListener

dispathTouchEvent(){
  if (onInterceptTouchEvent){
    if (onTouchListener){
      if (! onTouchListener.onTouch){
        self.onTouchEvent(); -> if (onClickListener){listener.onClick}
      }
    }
  }else {
    child.dispathTouchEvent();
  }
}

onTouchEvent(){

}
  • view 滑动冲突处理
    1. 外部拦截:在父容器的onInterceptTouchEvent中进行拦截,
public boolean onInterceptTouchEvent(MotionEvent event){
  boolean intercept = fasle;
  int x = (int) event.getX();
  int y = (int) event.getY();
  switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
      intercept = false;
      break;
    case MotionEvent.ACTION_MOVE:
      if(parentIntercept()){
        intercept = true;
      }else {
        intercept = false;
      }
      break;
    case MotionEvent.ACTION_UP:
      intercept = false;
      break;
  }
  return intercept;
}
  1. 外部拦截:在子容器中进行处理,重写子容器的dispathTouchEvent,需要通过requestDisallowInterceptTouchEvent()设置父容器是否拦截,同时父容器需要重写onInterceptTouchEvent拦截除了ACTION_DOWN以外的事件。
//子容器
public boolean dispathTouchEvent(MotionEvent event){
  switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
      requestDisallowInterceptTouchEvent(true);
      break;
    case MotionEvent.ACTION_MOVE:
      if (parentIntercept()){
        requestDisallowInterceptTouchEvent(false);
      }
      break;
    case MotionEvent.ACTION_UP:
      break;
  }
  return super.dispathTouchEvent(event);
}

//父容器
public boolean onInterceptTouchEvent(MotionEvent event){
  if (event.getAction() == MotionEvent.ACTION_DOWN){
    return false;
  }
  return true;
}
  • view工作原理
    DecorView(是一个FrameLayout)作为顶级view,一般包含一个竖直方向的LinearLayout,LinearLayout里有上下两部分,上面为titleBar,下面是android.R.id.content,所以是setContentView,view层事件都先经过DecorView。

MeasureSpec 32bit int值, 前2位代表specMode,后30位代表specSize
specMode 有三种:
UNSPECIFTED — 父容器不对view有任何限制
EXACTLY — 监测出view的精确大小,对应 match_parent 和具体数值
AT_MOST — 父容器指定一个可用的大小,view大小不能大于这个值,对应于 wrap_content

view 工作流程 measure layout draw
1. measure 直接继承view的自定义控件,如果不重写onMeasure,使用wrap_content效果和match_parent效果一样。
对于viewgroup,除了完成自己的measure,还要遍历调用所有子元素的measure。
onMeasure中经过计算,最终调用setMeasuredDimension()。
view 的 onMeasure和activity的onCreate onResume onStart方法不是同步执行的,不能保证执行onCreate等时view已经测量完成。如果没有测量完成,此时获取到的view的宽高为0。
获取view宽高为0解决方法:
1. onWindowFocusChanged() view此时已经初始化完毕,此方法会调用多次
2. view.post(new Runnable(){
public void run(){
int w = view.getMeasuredWidth();
int h = …;
}
})
3. ViewTreeObserver
ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
public void OnGlobalLayout(){
observer.removeGlobalOnLayoutListener(listener); //因为view树状态改变或者view可见性发生改变时都会调用OnGlobalLayout方法,所以此处注销监听器。
int w = …;
int h = …;
}
});
4. view.measure()中手动测量

  1. layout view的layout中调用onLayout,onLayout中遍历调用子元素的layout。

  2. draw 流程

    1. 绘制背景 
    2. 绘制自己 onDraw()
    3. 绘制children dispathDraw()
    4. 绘制装饰 onDrawScrollBars()
android 消息机制

Handler MessageQueue Looper ThreadLocal

android 缓存图片

LruCache(LinkedHashMap) DiskLruCache
BitmapFactory.Options 加载缩小后的图片

android 性能优化
  • 内存泄露优化
    1. 静态变量导致内存泄露,

例:

static Context context;
onCreate(){
  context = this;
}

static View view;
onCreate(){
  view = new View(this);
}
  1. 单例模式导致内存泄露

  2. 属性动画导致内存泄露

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值