Android之Activity

Activity总结:

  1. Activity的顶层View是DecorView,而我们在onCreate函数中通过setContentView设置的View只不过是这个DecorView的一部分罢了。DecorView是一个FrameLayout类型的ViewGroup.
  2. Activity和UI有关,它包含一个PhoneWindow和LocalWindowManger对象。这两个对象控制整个Activity的显示。
  3. LocalWindowManger使用WindowMangerImpl作为最终的处理对象(Proxy模式)这个WindowMangerImpl对象有一个ViewRoot对象。
  4. ViewRoot实现了VIewParent接口,他有两个重要成员变量,一个是mView,他指向Activity顶层UI单元的DecorVIew,另一个是mSurface,这个Surface包含了一个Canvas。ViewRoot还通过Binder系统和WIndowManagerService进性跨进程的交互。
  5. ViewRoot能处理Handler的消息,Activity的现实就是由ViewRoot在他的performTravelsals函数中完成的。
  6. 整个Activity的绘画流程就是从mSurface中lock一块Canvas,然后交个mView去自由发挥画画的才能,最后unlockCanvasAndPOst释放这块Canvas。
  7. Service Activity本质上都是BInder的实现。 

概括的说就是Activity包括真实显示的窗口PhoneWIndow和在窗口中作画的人LocalWIndowManger,而作画的人手上有两个东西一个是存放画布的msurface,另一个就是作画的笔mview,客户端通过setContentView告诉画家他想要画的内容,然后画家根据客户的要求进性再创作(因为我们通过SetVontentVIew设置的view只不过是DecorView的一部分罢了)。当然画家还能和大自然保持沟通就是Binder机制。内部线程之间的沟通更是不可少所以能处理Handler的消息。一个Activey作为一个进程和所有的其他进程一样都有内部的通信机制和外部的通信机制,只是就Activity而言,内部的Handler机制因为应用更频繁所以被着重提出来了。

Activity分析:

  1. Activity的作画者ViewRoot的画布msurface是在哪里创建的哪?我们知道java世界有一个名为system_service的进程,这里管理者很多核心的管理者WindowMangerServer, PowerManagerServer,我们之前在从linux看android之二--java世界的盘古女娲里说过system_service维护着很多的java世界初始时候的核心服务。而surface其是在system_service进性的WindowMangerService里出生的。WMS(WindowMangerService)首先创建一个SurfaceComposerClent对象,然后调用SurfaceComposerCilent对象的createSurface得到一个SurfaceControl对象。最后是通过SufaceControl对象的writeToPacrel把surface相关的重要参数打包到邮包Parcel中。通过Binder机制邮寄到某个Activity进程里,之后就由Activity来初始化mSurface并lock画布作画和取消画布了。
    getSystemService("")  //Android在Activity中可以直接调用的这个方法获取管理对象就是system_service这个进程
  2. ViewRoot还有什么特征哪?ViewRoot是View试图体系的根。每个PhoneWidow都有一个ViewRoot,他的作用就是处理layout和view试图体系的绘制工作。所谓视图体系包括views和viewGroups,另外所有的View类都属于视图体系,view体系是要通过draw来画出来的。viewRoot就是用来draw他们的,但是ViewRoot本身没有Draw的能力,需要借助别人的方式,至少是必须经过viewroot的管理才能draw。viewroot的所有view都同属于一个画布就是Surface lock住的那个画布。画布里存放绘画结果的是bitmap,可以从字面理解这就是一个存放bit数据的map集合。所谓的绘画就是更改这个map集合的数据。viewRoot的作用就是根据view视图的描述,在指定的内存(就是surface lock住的那块区域)中产生一个具体的bitmap集合,然后在PhoneWIndow中根据bitmap渲染效果。
  3. 一个Activity就是一个进程。一位这个进程的作用更多的就是在于在界面上画出一个节目并完成和页面的交互。我分俩个方面来分析一下Activity这个进程和其他进程之间的通信就是IPC灯泡1.如果不考虑客户用Activity实现业务逻辑时候的IPC,只是分析不实现业务逻辑似乎的IPC,主要是首先在ViewRoot创建surface的时候,为了创建一个画布,这时候创建画布就要一下画布的主题等信息为了保持一个主题,所有的Activity必须继承自一个相同的主题风格。这个相同的主题风格就是由WMS来管理的,WMS会根据读取到的主题等信息,在自己的进程(也就是system_service)进程里把这些信息打包到Parcel中。当Activity向SystemService请求与WMS通讯建立服务连接的时候,systemService就会查询到WMS的引用返回给Activity,并且WMS还会回调Activity的onCreate方法,并且发送过来一些有用的信息在Bundle中。并且在这个过程中完成把Surface的邮包Parcel发送过来,从而直接为Activity分配了画布信息。由文章开始的总结我们知道我们通过setContentViews设置的view是DecorView的一部分,而Decorview就是RootView的一个重要的成员变量(viewRoot的成员变量mView指向的就是DecorView),如果onCreate函数执行的时候没有根据surface打包数据创建了画布这画界面等的操作就没法进性了。我们在Activity编程的大部分时候都是工作在onCreate函数下的。
  4. setContextView可以直接就用R.layout也可以用InflateLayout

package com.example.uridemo4;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class ActivityTest extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {#Bundle是WMS启动Activity的时候传过来的
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent =new Intent(this.getApplicationContext(), SQLiteActivity.class);
        startActivity(intent);
    }

}

Activity功能测试代码:

package com.example.testactivity;

import com.example.testactivity.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class FirstActivity extends Activity{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
/**
1.所有的Activity都是有WindowManagerService 创建的。Activity需要启动的时候必须先与WMS建立连接。但是在Android中并不是 Activity直接去找WMS而是去找system_service,
         由system_service找到WMS再通知WMS,由WMS 启动Activity的Oncreate方法,所以savedInstanceState引用时WMS传过来的数据。正因为如此FirstActivity启动SecondActivity 的时候
         传给SecondActivity的数据不能从Bundle总获得之能从Intent中获得。
2.WMS同时传过来了ViewRoot的surface Parcel.
**/    
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.activity_first);//方式1:可以直接通过setContentView直接在viewRoot的mView中添加view
        
        Button button =(Button)findViewById(R.id.firstbutton);
        button.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
        Intent intent =new Intent(FirstActivity.this, SecondActivity.class);
        Bundle bundle=new Bundle();
        bundle.putString("test", "FirstActivity Bundle传值");
        intent.putExtras(bundle);
        startActivity(intent);
                
            }
        });
        
    }

}

 

package com.example.testactivity;

import com.example.testactivity.R;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class SecondActivity extends Activity {
    private Button button;
    private TextView textView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        
//       String test1=savedInstanceState.getString("test");
//        if(test1==null){
//            test1="null";
//        }
        if(savedInstanceState==null){
            
            Log.d("sendcondActivity   1", "null");//运行结果输出为null 说明这个Bundle是WMS的Bundle 不是FirstActivity包装的Bundle。
        }
        
        Bundle bundle =getIntent().getExtras();
        String test2=bundle.getString("test");
        Log.d("secondActivity   2", test2);//这里获得的数据就是FristActivity放入的值
        /***
         * 1.事实上每个activity 都有一个唯一的Intent 和Activity类对应。并且整也是因为Intent还能用来开启新的Activity所以这是 Activity之间通讯很重要的方法
         * 2.好比所有的Intent都保存在内存中,他们可以通过intent来唯一识别一个INtent intent如同数据库建表时候的主键 当然还有分类信息(Action catogory等信息)
         * 
         * 
         */

//        第二种方式添加View到RootView 用LayoutInfalter也是system_service提供的服务。
        LayoutInflater layoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view =layoutInflater.inflate(R.layout.activity_second, null);
         button =(Button)view.findViewById(R.id.secondbutton);
         button.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                textView.setText("SecondeActivity点击了按钮");
                
            }
        });
         textView=(TextView)view.findViewById(R.id.secondtextview);
         setContentView(view);//这是通过SetCOntentView来吧view试图加载到viewroot上
    }
    

}

 

代码下载:TestActivity

拓展阅读:深入理解Android

原文地址:https://www.cnblogs.com/zhanghaiyublog/p/3619463.html