一、app的运行方式

    操作系统会给每一个andorid应用程序(App)分配一个唯一userId。所以每一个App都是以一个独立的用户运行在android操作系统之上。

二、app的framework组成

 

    android的App框架主要包含三大核心组件Activity、Service、BroadcastReceiver和一个重要消息承载组件Intent。

1)Activity

    Activity是一个掌控与UI交互的一个组件。负责加载UI的layout,并注册UI上的可视化组件的监听器(比如一个button的click事件的监听处理器)。使用activity需要关注他的生命周期不同阶段所调用的方法,这些方法和对应的activity状态关系可以参考下图。


 更多详情参阅这里

2)Service

    Service是提供后台逻辑处理的组件,不与UI进行绑定,用来在后台处理耗时较长的任务(注意需要另起线程处理,因为service仍然是在他的host线程运行的)。

    该组件有两种使用方式:

    a)startService():某一组件调用startService()来启动service,启动后即使负责启动的组件已经失效(destoryed)该service仍然可以存在并并运行。

    b)bindService():一般情况下是用activity绑定一个service,这样activity和service可以一起交互协作。当绑定在service上的所有组件都unbund之后,该service才会被销毁。

生命周期和相关的调用方法如下图所示:

更多详情参考这里

3)broadcastReceiver 

    BroadcastReceiver是为了实现系统广播而提供的一种组件。比如,我们可以发出一种广播来测试手机wifi信号连接的变化,这时候就可以定义一个BraodcastReceiver来接受广播,当wifi连接上internet时可以提示用户可以更新一写软件。我们可以用Intent配合sendBroadcast()方法发起一个系统级别的事件广播来传递消息。当然我们也可以在自己的应用程序中实现BroadcastReceiver来监听和响应广播的Intent。broadcastReceiver的生命周期非常短暂,仅用户持续与onReceive()方法,而且该方法一般情况下不能够长时间的执行,而且在该方法中启动的thread会在该方法返回后销毁,所以一般在这里启动service来处理消息。

更多信息参考这里

4)intent

    Intent对象就是一个信息包(bundle),他主要包含接受处理该intent的组件关心的信息数据和android系统关心的信息数据。

更多信息参考这里

三、一个helloworld的实例

    根据以上三个核心组件和信息承载组件Intent的知识,我们做一个负责一点的helloworld的例子来练下手。大家先参考google等在本地安装起来一个环节,并创建一个初步的helloworld的例子。一般的网上找的这个例子只是一个初步的包含了activity组件的例子。我带着大家一起改造下这个项目,将三大核心组件都加入进来(其实app框架是有四大重要组件的,除了我们提到的三大核心组件还有另外一个contentprovider暂时先不讲)。

0)App项目程序结构和App demo逻辑

大家根据google来的信息肯定已经先搭起来了一个只包含了activity的例子。先简单的介绍下这个项目的程序代码结构,如下图。


 

为了练手3大核心组件,我们设计一个简单的场景,用户在界面上输入一个字符串,然后点击一个广播的按钮,通过该按钮触发一个系统广播(即发送一个自定义的广播信息,在Activity中绑定具体UI组件的事件监听器),然后我们再顶一个广播信息的接受者来处理这个消息(BroadcastReceiver),具体的处理触发动作我们放到一个service中在后台处理,具体的处理逻辑是在屏幕上显示一下这个输入信息,并且渐隐。

 2)下面是具体的实现逻辑代码的核心部分。请参考。

andoridmanifest.xml文件,这里配置了整个app组件信息

 

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.myfirstapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <!-- 指定适用的sdk信息 -->
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <!-- 应用组件的配置,主要配置activity、service、broadcastReceiver 、contentProvider -->
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <!-- 配置启动要使用的主Activity -->
        <activity
            android:name="com.example.myfirstapp.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
		<!-- 配置系统消息的接收器 -->
        <receiver android:name="MyReceiver" >
            <intent-filter>
                <!-- 指定接受消息的action名称-->
                <action android:name="com.example.action.MyAction" />
            </intent-filter>
        </receiver>
		<!-- 配置我们的消息处理服务 -->
        <service
            android:name="MyService"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.ACTION_SCREEN_ON" />
            </intent-filter>
        </service>
    </application>

</manifest>

 /res/layout/layout_main.xml配置了我们的交互UI的组件,虽然此处很简单只有2个按钮和2个textview但是我们后台的逻辑都是通过这里触发的。

 

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/button1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="32dp"
        android:text="@string/button1" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="text" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/button2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/button2" />

</LinearLayout>

 com.example.myfirstapp.MainActivity.java文件,我们的系统中的Activity,修改后代码如下。

 

 

//activity需要继承android.app.Activity
public class MainActivity extends Activity {
	private Boolean clickSign = false;
	private final static String MY_ACTION = "com.example.action.MyAction";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//装载UI的Layout
		setContentView(R.layout.activity_main);
		//获取页面各组件
		final TextView hello = (TextView) this.findViewById(R.id.textView1);
		final TextView info = (TextView)this.findViewById(R.id.editText1);
		Button button = (Button) this.findViewById(R.id.button1);
		Button broadcastBtn = (Button)this.findViewById(R.id.button2);
		//绑定页面按钮的click事件监听器
		button.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				if(!clickSign){
					hello.setText(R.string.tttttt);
				}else{
					hello.setText(R.string.hello_world);
				}
				clickSign = !clickSign;
			}
			
		});
		//点击该按钮后将会发送系统消息
		broadcastBtn.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				CharSequence infoText = info.getText();
				Intent intent = new Intent();
				intent.setAction(MY_ACTION);
				intent.putExtra("msg", "your input info:"+infoText);
				sendBroadcast(intent);
			}});
	}

}

 com.example.myfirstapp.MyReceiver我们的定义Receiver。

 

//系统消息接收器,可以跨系统接受消息,需要继承自android.content.BroadcastReceiver
public class MyReceiver extends BroadcastReceiver {  
  
    @Override  
    public void onReceive(Context context, Intent intent) {  
    	
        String msg=intent.getStringExtra("msg");  
        //构造启动消息处理服务的intent
        Intent serviceIntent=new Intent(context, MyService.class);
        serviceIntent.putExtra("msg", msg);
        //启动服务
		context.startService(serviceIntent);
    }  
      
}

 com.example.myfirstapp.MyService定义service,具体信息可以参照下面的代码和注释

//service 需要继承android.app.Service
public class MyService extends Service {
	
	@Override
	public IBinder onBind(Intent intent) {
		//Unbund Service 此处可以返回空
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		int result = super.onStartCommand(intent, flags, startId);
		//拿到消息数据并展示,如果此处消息的处理比较耗时可以启动线程进行处理
		String msg = intent.getStringExtra("msg");
		Toast.makeText(this, "msg received in service.msg is---"+msg, Toast.LENGTH_LONG).show();
		return result;
	}

}