On the android

Andrews system is divided into four layers:

  linux kernel Layer: providing a drive to the Andrews device hardware;

  Runtime layer system: some of the c / c ++ library that supports Android. As sqlite support database; open-gl support 3d graphics; webkit browser that supports kernel; some of the core library of java language library support Android applications Android Runtime

  Application Framework Layer: Andrews provides some coding API;

  Application Layer: The application on the phone;

Four components Andrews:

  Activities (Activity, applications see things), service (Service, running in the background), the broadcast receiver (Brocast Receiver, telephone, SMS, etc.), content provider (Content Provider, sharing data between applications)

 

Activity:

Activity Status:

  Active, the top of the stack of pages;

  Suspended state, non-top of the stack, but visible;

  Stop state, non-top of the stack, invisible, its member variables and status might be recovery system;

  The destruction of the state, removed from the stack, the system will recover out.

Activity life cycle:

  onCreate (): when the page was first created in the call to complete the page layout, initialization, binding and other events;

  onStart (): page called by the invisible to visible state;

  onResume (): page already and user interaction; ---- requestLayout () to draw the layout process, and will checkThread (). After checking the thread method calls, you can not update the UI in the sub-thread.

  onPause (): about to enter or load another page, you can free up some resources, such as: file handles, timers, sqlite of operation;

  onStop (): page completely invisible when the call;

  onDestroy (): call when the page is destroyed;

  onRestart (): page becomes visible again when the call;

onSaveInstanceState (Bundle bundle): to save the current activity variable or by data bundle, taken out in the onCreate.

 

getTaskId () task id. A task is represented by a start app, and do jump in activity app, as well as jump to another track recording app page.

activity of lauchmode: 1, standard, standard load mode, the normal task stack

          2, singleTop, if activity in the top of the stack, then call onNewIntent (), if not in the top of the stack, the similar standard, into the top of the stack

          3, singleTask, the entire activity task stack will have only one activity, the activity will only repeat calls onNewIntent (), if the current activity is not the top of the stack, the stack of activity calls onDestroy ()

          4, singleInstance, similar to singleTask, but will generate a task the task stack.

 

A app startup, automatically starts a main thread, and then call ActivityThread the main function, call Looper.prepareMainLooper () to create a Looper object and call Looper.loop () processes the message queue and user practices. ActivityThread is an ordinary class, not a thread class. After ActivityThread start, calls the remote agent ActivityManagerNative.getDefault ActivityManagerService of () and attach (ApplicationThread objects) and AMS interact.

 

Instrumentation is mainly used to create application objects, start the activity and manage activity lifecycle callbacks.

 

H extents handle main processing messages sent from ActivityManagerService:

  handleLauchActivity: Activity by classLoader loading;

            Call activity.attach () windowManager the activity and associated management activity page display;

 

AMS offers an ArrayList mHistory to manage all the activity, activity in the form of AMS is ActivityRecord, in the form of task for the AMS in TaskRecord, forms of management processes in the AMS is ProcessRecord. As shown below

 

  • All ActivityRecord will be stored in mHistory management;

  • Each ActivityRecord will correspond to a TaskRecord, and has the same TaskRecord ActivityRecord in mHistory will at discrete positions;

  • With a TaskRecord of Activity may be in a different process, respectively, each Activity in which the process has nothing to do with the task;



When the Activity starts ActivityManagerService will generate a corresponding record for ActivityRecord and add it to the fallback stack (back stack), the other will be added to the record ActivityRecord a Task. Remember, ActivityRecord, backstack, Task objects are ActivityManagerService by ActivityManagerService process is responsible for the maintenance, rather than maintained by the application process.
 
Belong to the same task in the stack ActivityRecord rollback will be placed together, will form a stack structure, that is to say after the start of the corresponding ActivityRecord Activity will be on top of the stack of task
 
Fragment:
 
 
Lifecycle schematic above.
  • onAttach (): Called when Fragment and associated Activity. Activity may be obtained by reference to the method, may further () Gets parameters getArguments.
  • onCreate (): Fragment call when they are created.
  • onCreateView (): Fragment of creating a layout.
  • onActivityCreated (): Called when the Activity is completed onCreate ().
  • onStart (): Called when the Fragment visible.
  • onResume():当Fragment可见且可交互时调用。
  • onPause():当Fragment不可交互但可见时调用。
  • onStop():当Fragment不可见时调用。
  • onDestroyView():当Fragment的UI从视图结构中移除时调用。
  • onDestroy():销毁Fragment时调用。
  • onDetach():当Fragment和Activity解除关联时调用。

1、Fragment的onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()都是在Activity的onStart()中调用的。

2、Fragment的onResume()在Activity的onResume()之后调用。

3、当点击F1的按钮,调用replace()替换为F2,且不加addToBackStack()时,F1最后调用了onDestroy()onDetach()

4、当点击F1的按钮,调用replace()替换为F2,且加addToBackStack()时,F1被替换时,最后只调到了onDestroyView(),并没有调用onDestroy()onDetach()。当用户点返回按钮回退事务时,F1会调onCreateView()->onStart()->onResume()。

 

FragmentTransaction有一些基本方法,下面给出调用这些方法时,Fragment生命周期的变化:

  • add(): onAttach()->…->onResume()。
  • remove(): onPause()->…->onDetach()。
  • replace(): 相当于旧Fragment调用remove(),新Fragment调用add()。
  • show(): 不调用任何生命周期方法,调用该方法的前提是要显示的 Fragment已经被添加到容器,只是纯粹把Fragment UI的setVisibility为true。
  • hide(): 不调用任何生命周期方法,调用该方法的前提是要显示的Fragment已经被添加到容器,只是纯粹把Fragment UI的setVisibility为false。
  • detach(): onPause()->onStop()->onDestroyView()。UI从布局中移除,但是仍然被FragmentManager管理。
  • attach(): onCreateView()->onStart()->onResume()。
调用commit() 不会立即执行事务,而是在 Activity 的 UI 线程(“主”线程)可以执行该操作时再安排其在线程上运行。不过,如有必要,您也可以从 UI 线程调用  executePendingTransactions()以立即执行 commit() 提交的事务。通常不必这样做,除非其他线程中的作业依赖该事务。
 
DialogFragment显示浮动对话框。使用此类创建对话框可有效地替代使用Activity 类中的对话框帮助程序方法,因为您可以将片段对话框纳入由 Activity 管理的片段返回栈,从而使用户能够返回清除的片段。
 
 
ListView:
view的显示分为三步骤:1、onMeasure();2、onLayout();3、onDraw()
 
  
 
  • mCurrentScrap:ArrayList类型,用于存储离屏的 View
  • mScrapViews
    • ArrayList[] 类型
    • 数组中每个元素都是 ArrayList类型,效果同 mCurrentScrap
    • mScrapViews[0] 就是 mCurrentScrap
    • 其数组长度应为 ViewTypeCount。因为针对不同的 ViewType,ListView 都要有一个专门的 ArrayList链表来缓存它对应的 View
  • mActiveView:ArrayList类型,被 layoutChildren() 用于缓存屏幕上的 View。
    • 假设在某一时刻ListView中显示了10个子View,position依次为从0到9。然后我们手指向上滑动,且向上滑动了一个子View的高度,ListView需要绘制下一帧。这时候ListView在layoutChildren方法中把这10个子View都放入到了RecycleBin的mActiveViews数组中了,然后清空了children数组,然后调用fillDown方法,向ListView中依次添加position1到10的子View,在添加position为1的子View的时候,由于在上一帧中position为1的子View已经被放到mActiveViews数组中了,这次直接可以将其从mActiveViews数组中取出来,这样就是直接复用子View,所以说RecycleBin的mActiveViews数组主要是用于直接复用的。
 
Adapter是适配器的意思,它在ListView和数据源之间起到了一个桥梁的作用,借助Adapter这个桥梁来去访问真正的数据源,Adapter的接口都是统一的,因此ListView不用再去担心任何适配方面的问题。而Adapter又是一个接口(interface),它可以去实现各种各样的子类,每个子类都能通过自己的逻辑来去完成特定的功能,以及与特定数据源的适配操作,比如说ArrayAdapter可以用于数组和List类型的数据源适配,SimpleCursorAdapter可以用于游标类型的数据源适配。
 
在展示listview的第一屏时,所有的子View都是调用LayoutInflater的inflate()方法加载出来的,这样就会相对比较耗时。
 
当ListView向下滑动的时候,就会进入一个for循环当中,从上往下依次获取子View,子View都按照传入的参数值进行相应的偏移,这样就实现了随着手指的拖动,ListView的内容也会随着滚动的效果。如果这个子View已经移出屏幕了,将这个View加入到废弃缓存当中,并将子View给detach掉。并将count计数器加1,计数器用于记录有多少个子View被移出了屏幕。
 
如果ListView中有新的子View移入屏幕就会尝试从废弃缓存中获取View。所以它们之间就形成了一个生产者和消费者的模式,ListView中的子View其实来来回回就那么几个,移出屏幕的子View会很快被移入屏幕的数据重新利用起来,因而不管我们加载多少数据都不会出现OOM的情况,甚至内存都不会有所增加。
 
getView()方法来去获取一个View。就是我们平时使用ListView时最最经常重写的一个方法了,这里getView()方法中传入了三个参数,分别是position,convertView和this。convertView就是我们之间利用过的View,只不过被移出屏幕后进入到了废弃缓存中,现在又重新拿出来使用而已。然后我们只需要把convertView中的数据更新成当前位置上应该显示的数据,那么看起来就好像是全新加载出来的一个布局一样
 
 
RecyclerView:

RecyclerView 滑动场景下的回收复用涉及到的结构体两个:mCachedViews 和 RecyclerViewPool,mCachedViews 优先级高于 RecyclerViewPool。

回收时,最新的 ViewHolder 都是往 mCachedViews 里放,如果它满了,那就移出一个扔到 ViewPool 里好空出位置来缓存最新的 ViewHolder。

复用时,也是先到 mCachedViews 里找 ViewHolder,但需要各种匹配条件,概括一下就是只有原来位置的卡位可以复用存在 mCachedViews 里的 ViewHolder,如果 mCachedViews 里没有,那么才去 ViewPool 里找。

在 ViewPool 里的 ViewHolder 都是跟全新的 ViewHolder 一样,只要 type 一样,有找到,就可以拿出来复用,重新绑定下数据即可。 

 

一定要全部替代ListView?

  NO!!!列表页展示界面,需要支持动画,或者频繁更新,局部刷新,建议使用RecyclerView,更加强大完善,易扩展;其它情况(如微信卡包列表页)两者都OK,但ListView在使用上会更加方便,快捷。

 

ListView的缓存机制对比:

RecyclerView比ListView多两级缓存,支持多个离ItemView缓存,支持开发者自定义缓存处理逻辑,支持所有RecyclerView共用同一个RecyclerViewPool(缓存池)。

RecyclerView 中的一缓 mAttachedScrap 与 ListView 中的一缓 mActiveViews 功能是基本相似的,为了屏幕内 item 快速复用而存在

RecyclerView 中的二缓 mCachedViews 加上四缓 RecyclerViewPool 合在一起与 ListView 的二缓 mScrapedViews意义相同,为了即将给即将入屏的 item 复用而存在。
RecyclerView的优势在于
  a.mCacheViews的使用,可以做到屏幕外的列表项ItemView进入屏幕内时也无须bindView快速重用;
  b.mRecyclerPool可以供多个RecyclerView共同使用,在特定场景下,如viewpaper+多个列表页下有优势.客观来说,RecyclerView在特定场景下对ListView的缓存机制做了补强和完善。



广播

  Android中的广播使用了观察者模式,基于消息的发布/订阅事件模型。因此,从实现的角度来看,Android中的广播将广播的发送者和接受者极大程度上解耦,使得系统能够方便集成,更易扩展。

  1.广播接收者BroadcastReceiver通过Binder机制向AMS(Activity Manager Service)进行注册;

 

  2.广播发送者通过binder机制向AMS发送广播;

 

  3.AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;

 

  4.消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。

 

  

  同一app内部的同一组件内的消息通信(单个或多个线程之间),实际应用中肯定是不会用到广播机制的(虽然可以用),无论是使用扩展变量作用域、基于接口的回调还是Handler-post/Handler-Message等方式,都可以直接处理此类问题  

  同一app内部的不同组件之间的消息通信(单个进程),对于此类需求,在有些教复杂的情况下单纯的依靠基于接口的回调等方式不好处理,此时可以直接使用EventBus等,相对而言,EventBus由于是针对统一进程,用于处理此类需求非常适合,且轻松解耦。

  

EventBus

EventBus.getDefault().register(this);意思是让EventBus扫描当前类,把所有onEvent开头的方法使用Map,Key为方法的参数类型,Value中包含我们的方法记录下来。这样在register执行完成以后,我们的onEventMainThread就已经以键值对的方式被存储到EventBus中了。 EventBus会根据post中实参的类型,去Map中查找对应的方法,于是找到了我们的onEventMainThread,最终调用反射去执行我们的方法。

 

单例的写法:

 

private EventBus instance;

public static EventBus shareInstance() {

  if (instance == null) {

    synchronized (EventBus.class) {
      if (instance == null) {
        instance = new EventBus();
      }
    }
  }
  return instance;

}

 

反射

Java 开发中定义一个类,往往是要通过许多修饰符来配合使用的。它们大致分为 4 类。

  • 用来限制作用域,如 public、protected、priviate。
  • 用来提示子类复写,abstract。
  • 用来标记为静态类 static。
  • 注解。

Class

获取Class:

  如果这个对象可以访问,那么调用 getClass()方法就可以获取到了它的相应的 Class 对象。这种方法不适合基本类型如 int、float 等等。不想创建这个类的实例的话,就需要通过 `.class` 这个标识。如果当前类不在开发环境中,那么可以通过传入一个类的全限定名称给Class.forName()获取Class

获取ClassName:

  getName()返回类的全限定名称

  getSimpleName()返回嵌套类内的类名

获取修饰符:

  Modifier.toString(xx.class.getModifiers())

Field

获取属性:

  Class.getDeclaredFields()//获取所有的属性,但不包括从父类继承下来的属性,访问了 private 修饰的成员,需要添加. field.setAccessible(true);

  Class.getFields()//获取自身的所有的 public 属性,包括从父类继承下来的属性。

获取属性类型:

  field.getType()//属性类型

  field.getGenericType()//包含泛型在内的属性类型

获取属性修饰符:类似于获取类的修饰符

获取属性的值:

  field.get(obj)

设置属性的值:

  field.set(obj,value)

Method

获取方法:

  Class.getDeclaredMethod()//获取所有的方法,但不包括从父类继承下来的方法

  Class.getMethod()//获取自身的所有的 public 方法,包括从父类继承下来的方法。

获取方法名:

  method.getName()

获取方法修饰符:类似于获取类的修饰符

获取参数:

  method.getParameters()//返回Parameter 数组

获取参数名:

  Parameter.getName()

获取参数类型:

  Parameter.getType()

  Parameter.getGenericType()//包含泛型在内的参数类型

获取参数修饰符:

  Parameter.getModifiers()

获取返回值类型:

  method.getReturnType()

  method.getGenericReturnType()//包含泛型在内的返回值类型

获取异常类型:

  method.getExceptionTypes()

  method.getGenericExceptionType()//包含泛型在内的异常类型

执行某个方法:

  method.invoke(obj,obj...args)

Constructor

获取构造方法:

  Class.getDeclaredConstructor()//获取当前类的所有构造方法

  Class.getConstructor()//获取当前类自身的所有的 public 构造方法

访问构造方法:

  Constructor.newInstance()

Array

获取数组元素类型:

  array.getComponentType()//Car[] 返回com.array.test.Car

动态创建数组:

  Array.newInstance(Class<?> componentType, int... dimensions)

数组的读取和赋值:

  arr.set(obj,value)

  arr.get(obj)

Enum
Class.isEnum()// 用来判定当前 Class 对象是不是枚举类型

Class.getEnumConstants()//获取当前类的所有的枚举常量

Field.isEnumConstant()//获取某属性是否为枚举常量

 

Looper


Looper中几个关键对象:Thread,
Looper,MessageQueue,Handler,Message

可以从一个线程创建关联到另一个线程 Looper 的 Handler,只要能拿到对应线程的 Looper 实例。

Handler---发送和处理与某线程的 MessageQueue 相关联的 Message/Runnable 对象。每个 Handler 实例只能与一个线程和它的消息队列相关联。它将 Message 和 Runnable 传递给绑定的消息队列,并在它们从队列里被取出时执行对应逻辑。

  Runnable 被封装成 Message 之后添加到 MessageQueue。Runnable 对象是被封装成 Message 对象后加入到消息队列的,Message.callback 被设置为 Runnable 本身

  创建 Handler 实例时要么提供一个 Looper 实例,要么当前线程有关联的 Looper。

  handler操作的MessageQueue是线程安全的,MessageQueue的message入队方法,使用了synchronized关键字

public class Handle {

  final Looper mLooper

  final MessageQueue mQueue;

  final Callback mCallback;

  public Handle(Looper looper,Callback callback,bool aysnc) {

    if (looper == null) {throw 一个异常}

    mLooper = looper;

    mQueue = looper.mQueue;

    mCallback = callback;

  }

  public boolean enqueueMessage(MessageQueue mQueue,Message message, long updateTime) {

    message.target = this;

  }

  private static void handleCallback(Message message) {

    message.callback.run();

  }

  public void dispatchMessage(Message message) {

    if (message.callback != null) handleCallback(message);

    else if (mCallback != null) {

      if (mCallback.handleMessage()) return;

      handleMessage();

    }

  }     

}

MessageQueue---是作为Looper的一个成员变量而存在,当Looper实例化的时候,它也被初始化,并且当前的Thread对象也当做成员变量存起来。

Looper---Looper.prepare():创建一个Looper,并且将这个Looper存储到一个静态ThreadLocal变量中,而Looper中关联着Thread对象。注意如果当前线程已有Looper它会抛异常。

     Looper.loop():就是进入一个死循环,不断的从MessageQueue中取出Message,然后拿到Message.target,也就是Handler,执行它的dispatchMessage方法。

   另注: ThreadLocal的set和get方法可视为获取到了looper.mThread用来和looper一一对应

public final Class Looper {

   final MessageQueue mQueue;

  Thread mThread;

  public static void prepare() {

    if (sThreadLocal.get() != null) {throw一个异常}

    sThreadLocal.set(new Looper())

  }

  private Looper() {

    mQueue = new MessageQueue()

    mThread = Thread.currentThread()

  }

  public static Looper myLooper() {

    return sThreadLocal.get()

  }

  public static void loop() {
    while(true) {

      Message message = mQueue.next()

      message.target.dispatchMessage(message)

    }

  }

}

 Service

一些关于其定义和使用的东西:https://blog.csdn.net/guolin_blog/article/details/11952435
 
  
 
全局获取context方法:
新建MyApplication extends Application {
    private static Context context;
    public void onCreate() {
      context = getApplicationContext();
      LitePalApplication.initialize(context);//如果已经配置了LitePal类似的application
    }
    public static Context getContext() {return context}
  }
修改AndroidManifest.xml 的 <application>标签 指定他的android:name="com.xxx.xxx.MyApplication"
就可以在全局通过MyApplication.getContext()获取了
 
Bitmap
内存管理:使用完bitmap,及时使用 Bitmap.recycle()回收。
缓存: 内存缓存硬盘缓存
图片大小:使用ImageView显示Bitmap时会占很多资源,使用 BitMapFactory.Options对图片进行压缩。
     android默认颜色模式为 ARGB_8888,显示质量最高,占用内存最大。若要求不高时可采用 RGB_565等模式。
图片大小:图片长度*宽度*单位像素所占据字节数
      ARGB_4444:每个像素占用2byte内存
      ARGB_8888:每个像素占用4byte内存 (默认)
      RGB_565:每个像素占用2byte内存
捕获OOM异常:程序中设定如果发生OOM的应急处理方式。清理内存空间,强制Bitmap.recycle()回收等
 
 
引用类型

一:强引用

只要引用存在,垃圾回收器永远不会回收,当内存空间不足,Java 虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
Object obj = new Object();

后面有若干个方法用到obj 如自定义方法:hanlde(obj );
只有当hanle方法执行完之后,obj这个引用被释放,对象才会被释放掉,这也是我们经常所用到的编码形式。

二:软引用

非必须引用,内存溢出之前进行回收,可以通过以下代码实现
Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null;
sf.get();//当内存不足时可能null
这时候sf是对obj的一个软引用,通过sf.get()方法可以取到这个对象,当然,当这个对象被标记为需要回收的对象时,则返回null;

如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就
会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的
高速缓存。

三:弱引用

弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内
存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

四:虚引用

"虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被
垃圾回收的活动。

 

HashMap

数组形式储存,链表辅助。put()的时候通过map的键对象的hashCode寻找下标,如果改下标有元素,则下标往后移。如果元素达到了hashmap容量的75%,则进行扩容为原来的两倍。get()的时候也是通过对比键对象的hashCode和equals()取出对应的map。

 

APK签名机制

1、程序遍历apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个生成SHA1的数字签名(类似摘要MD5)信息,再用Base64进行编码。生成MANIFEST.MF文件

2、对前一步生成的Manifest,使用SHA1-RSA算法,用私钥进行签名。生成CERT.SF文件

3、CERT.RSA文件中保存了公钥、所采用的加密算法等信息

Guess you like

Origin www.cnblogs.com/diyigechengxu/p/11113946.html