android的service

package com.service.service;



import com.example.service.R;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;

import android.view.View;
import android.widget.Toast;
/**
 * service組件
 * 1.定義一個類繼承Service類
 * Service兩種啓動方式
 * 	<1>.start
 * 	<2>.onBind
 * 服務對象同時只有一個
 * 默認情況下,一個started的service與啓動它的應用組件在同一線程中,
 * 所以如果我們使用service來完成一些好使的操作任務時,就會阻塞主線程
 * 那我們就必須在線程中來處理耗時任務
 * 停止一個服務的兩種方法
 * <1>.在外部使用stopService()
 * <2>.在服務類內部使用stopSelf()
 * 
 * IntentService
 * 該類型的service會在單獨的線程中執行任務,任務完成後會自動結束service
 * 當我們有需要這樣一次性完成的任務就可以使用IntentService來完成
 * 
 * 
 * 
 * IPC(進程間的通訊)
 * AIDL(android接口定義語言)
 * 使用aidl定義業務接口,通過ADT工具來生成一個java類,此類實現了進程間遠程通訊的代理
 * 編寫自己的業務類(繼承生成的類中的stub存根)來實現業務接口
 * 再通過綁定service的方式來暴露此業務對象給其他組件提供功能
 * 
 * 調用者組件通過servuce方法綁定服務,從而可以獲取綁定成功後的遠程業務對象或本地對象
 * 可以調用相關的功能
 * 注意:一般在使用完綁定服務後,需要解除綁定
 * 
 * 自定義AIDL對象
 * 1.需要自自定義的類型上實現Parcelable接口
 * 2.需要定義一個aidl文件來申明自定義類型(在student。aidl文件中申明 parcelable Student;)
 * 3.在使用該自定義類型時必須使用import語句導入該自定義類型,否則報錯
 * 
 * 
 * 
 * 使用started與bing服務之間的區別
 * 使用started會一直運行在後臺,需要服務本身或外部組件停止服務纔會結束運行
 * 通過bind的服務,它的生命週期依賴綁定的組件,
 * 1.started服務可以給啓動的對象傳遞參數,但無法獲取服務中的方法返回
 * 2.可以給啓動的服務對象傳遞參數,也可以通過綁定的業務對象獲取返回結果
 * 在實際應用中的使用技巧
 * 1.第一次先使用started來啓動一個服務,
 * 之後可以使用綁定的方式綁定服務,從而可以直接調用業務方法返回值
 * */
public class MainActivity extends Activity {
	private IPerson person;    //要使用的業務對象接口
	boolean flag=false;
	//服務連接對象
	private ServiceConnection serviceConnection=new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			//當服務異常終止時會調用,注意:解除綁定服務時不會調用
			System.out.println("onServiceDisconnected");
			flag=false;
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			//綁定成功後服務會回調該方法,自動傳入IBinder對象
			System.out.println("onServiceConnected");
			person= IPerson.Stub.asInterface(service);
			System.out.println(person);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	/**
	 * 啓動一個服務
	 * */
	public void start1(View view){
		System.out.println("start1");
		Intent intent=new Intent(this,HelloService.class);
		startService(intent);
	}
	public void stop(View view){
		System.out.println("stop");
		Intent intent=new Intent(this,HelloService.class);
		stopService(intent);
	}
	public void start2(View view){
		Intent intent=new Intent(this,HelloIntentService.class);
		startService(intent);
	}
	//綁定一個服務
	public void bindService(View view){
		System.out.println("bindService");
		Intent intent=new Intent(this,MyService.class);
		//參數(1.intent對象,2.服務連接對象,3.綁定服務的標記)
		flag=bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
	}
	//解除綁定服務
	public void unBindService(View view){
		if(flag){
			unbindService(serviceConnection);
			flag=false;
			
		}
		
	}
	//調用遠程業務對象方法(或是本地業務)
	public void callPerson(View view) throws RemoteException{
		person.setName("張三");
		person.setAge(21);
		person.setSex("男");
		String s=person.getPerson();
		Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
	}
	

activity_main.xml

<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: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="com.service.service.MainActivity" 
    android:orientation="vertical"
    >

   <Button 
       android:id="@+id/activity1_button1"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="啓動service1"
       android:onClick="start1"
       
       />
    <Button 
       android:id="@+id/activity1_button2"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="停止service1"
       android:onClick="stop"
       
       />
    
    

    <Button 
       android:id="@+id/activity1_button3"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="startIntentService"
       android:onClick="start2"
       
       />
    
     <Button 
       android:id="@+id/activity1_button4"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="綁定Service"
       android:onClick="bindService"
       
       />
      <Button 
       android:id="@+id/activity1_button5"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="解綁Service"
       android:onClick="unBindService"
       
       />
      
      
       <Button 
       android:id="@+id/activity1_callPerson"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="調用業務對象Person的方法"
       android:onClick="callPerson"
       
       />
</LinearLayout>

HelloService

package com.service.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class HelloService extends Service{
	private PersonImpl personImpl;
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return new PersonImpl();
	}
	//創建服務時調用
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.i("HelloService", "HelloServiceOnCreate");
	}
	//銷燬服務時調用
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.i("HelloService", "HelloServiceONDestory");
	}
	//服務執行時的操作
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i("HelloService", "HelloServiceONStartCommand");
		System.out.println("HelloServiceONStartCommand");
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				int i=0;
				for(;i<10;i++){
					System.out.println(Thread.currentThread().getName()+":"+i);
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				//HelloService.this.stopSelf(); //停止服務
			}
		}).start();
	
		
	
		return super.onStartCommand(intent, flags, startId);
	}
}

IPerson.aidl文件

package com.service.service;

interface IPerson {
	void setName(String name);
	void setSex(String sex);
	void setAge(int age);
	String getPerson();
}

PersonImpl

package com.service.service;

import android.os.RemoteException;

public class PersonImpl extends IPerson.Stub {
	private String name;
	private String sex;
	private int age;
	@Override
	public void setName(String name) throws RemoteException {
		// TODO Auto-generated method stub
		this.name=name;
	}

	@Override
	public void setSex(String sex) throws RemoteException {
		// TODO Auto-generated method stub
		this.sex=sex;
	}

	@Override
	public void setAge(int age) throws RemoteException {
		// TODO Auto-generated method stub
		this.age=age;
	}

	@Override
	public String getPerson() throws RemoteException {
		// TODO Auto-generated method stub
		return "name="+name+"sex="+sex+"age="+age;
	}

}

第二種:繼承IntentService

HelloIntentService

package com.service.service;

import android.app.IntentService;
import android.content.Intent;

public class HelloIntentService extends IntentService{

	public HelloIntentService() {
		super("IntentSerice");
		// TODO Auto-generated constructor stub
	}
	//該方法會在一個單獨的線程中執行,來完成工作任務
	//任務結束後,該service會自動停止
	@Override
	protected void onHandleIntent(Intent intent) {
		// TODO Auto-generated method stub
		for(int i=0;i<10;i++){
			System.out.println(Thread.currentThread().getName()+":"+i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		System.out.println("OnDestory");
	}

}

所有的service需要在清單文件中申明

 <service android:name="com.service.service.HelloService"></service>

 <service android:name="com.service.service.HelloIntentService"></service>


使用onBind方式

package com.service.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
/**
 * 實現一個綁定服務
 * 
 * */
public class MyService extends Service{
	private PersonImpl personImpl;
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		System.out.println("MyServiceOnCreate()");
	}
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		System.out.println("MyServiceOnBind()");
		personImpl=new PersonImpl();
		return personImpl;
		
	}
	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		System.out.println("MyServiceOnUnBind()");
		return super.onUnbind(intent);
	}

}


自定義AIDL

IStudent.aidl

package com.service.service;
import com.service.service.Student;
interface IStudent {
	void setStudnet(String name,String sex);
	Student getStudent();
}

Student.aidl

parcelable Student;

Student

package com.service.service;

import android.os.Parcel;
import android.os.Parcelable;

public class Student implements Parcelable{
	private String name;
	private String sex;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		// TODO Auto-generated method stub
		dest.writeString("name");
		dest.writeString("sex");
	}
	
	
	 public static final Parcelable.Creator<Student> CREATOR
     = new Parcelable.Creator<Student>() {
	 public Student createFromParcel(Parcel in) {
		 Student student=new Student();
		 student.setName(in.readString());
		 student.setSex(in.readString());
	     return student;
	 }
	
	 public Student[] newArray(int size) {
	     return new Student[size];
	 }
	};

}

StudentImpl

package com.service.service;

import android.os.RemoteException;
/**
 * 業務對象的實現
 * */
public class StudentImpl extends IStudent.Stub{
	private Student student;
	public StudentImpl(){
		student=new Student();
	}
	@Override
	public void setStudnet(String name, String sex) throws RemoteException {
		// TODO Auto-generated method stub
		this.student.setName(name);;
		this.student.setSex(sex);
	}

	@Override
	public Student getStudent() throws RemoteException {
		// TODO Auto-generated method stub
		return student;
	}

}

StudentService

package com.service.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class StudentService extends Service{
	private StudentImpl studentImpl;
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		studentImpl=new StudentImpl();
		return studentImpl;
	}

}

使用Messenge

MessageService

package com.service.service;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.widget.Toast;

public class MessageService extends Service{
    static final int MSG_HELLO=0x1;
	private Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case MSG_HELLO:
				Toast.makeText(MessageService.this, "hello", Toast.LENGTH_SHORT).show();
				break;

			default:
				break;
			}
		};
	};
	private Messenger messenger=new Messenger(handler);
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return messenger.getBinder();
	}

}

MessageActivity

package com.service.service;




import com.example.service.R;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.View;
/**
 * 使用Messenger實現IPC,
 * 1.Messenger是線程安全的,在service中創建一個Messenger對象並綁定一個handle
 * 2.在onBind方法中返回messenger對象,通過messenger的getIBinder方法返回一個IBinder對象
 * 3.在調用的組件中,ServiceConnection的onServiceConnection時間中,根據IBinder對象來創建一個Messenger對象
 * 這樣兩個Messenger對象就同事綁定到一個IBinder對象上,從而可以底線通信,
 * 在調用組件中方法種使用Messenger的send方法來發送消息到service的Messenger對象中
 * */
public class MessageActivity extends Activity{
	private Messenger messenger;
	private boolean mBound=false;
	private ServiceConnection conn=new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			if(mBound){
				mBound=false;
			}
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			messenger=new Messenger(service);
			mBound=true;
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.message_main);
	}
	
	
	public void useMessenger(View view){
		Message message=Message.obtain();
		message.what=MessageService.MSG_HELLO;
		try {
			messenger.send(message);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		Intent intent=new Intent(this,MessageService.class);
		bindService(intent, conn, Context.BIND_AUTO_CREATE);
	}
	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		if(mBound){
			unbindService(conn);
			mBound=false;
		}
	}
}

清單文件

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

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.service.service.MessageActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       <service android:name="com.service.service.HelloService"></service>
       <service android:name="com.service.service.HelloIntentService"></service>
        <service android:name="com.service.service.MyService" android:process=":remote"></service>
        <service android:name="com.service.service.StudentService"></service>
        <service android:name="com.service.service.MessageService"></service>
    </application>

</manifest>
<!-- android:process=":remote"設置運行在自己的進程中 -->


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章