embedded linux ,android

2010年11月14日 星期日

Android Service , aidl 與 Broadcast Receiver

什麼是service
沒有UI的程式,在背景執行的Process
啟動service的方式
1. startService(),stopService()
啟動 onCreate() --> onStart()
結束 onDestory()
若沒有StopService()則會繼續執行下去
2. bindService(),unbindService()
啟動onCreate() --> onBind()
結束onUnBind() --> onDestory()
啟動已執行起來的service,當然也可以啟動未執行起來的service
兩種方式可以混用,但必須stopService()且unbindService()才真正結束service


























demo code

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.wandroid.servicedemo"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".ServiceDemo"
                  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=".xxxService" android:exported="true"></service>
        <service android:name=".xxxRemoteService" android:process=":remote"/>
        <receiver android:name="xxxBroadcastReceiver">
           <intent-filter>
                 <action android:name="com.wandroid.servicedemo.Play_MUSIC"/>
         </intent-filter> 
      </receiver>
    </application>
    <uses-sdk android:minSdkVersion="7" />
</manifest> 
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:id="@+id/text"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<Button
  android:id="@+id/startservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="startService"
 />
<Button
  android:id="@+id/stopservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="stopService"
 />
<Button
  android:id="@+id/bindservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="bindService"
 />
<Button
  android:id="@+id/unbindservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="unbindService"
 />
<TextView  
    android:id="@+id/remotetext"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/remotehello"
    /> 
<Button
  android:id="@+id/remotebindservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="remote bindService"
 /> 
<Button
  android:id="@+id/remoteunbindservice"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="remote unbindService"
 />  
<Button
  android:id="@+id/musicbroadcast"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="music broadcast"
 /> 
</LinearLayout>
res/raw/music.mp3 res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, ServiceDemo!</string>
    <string name="app_name">ServiceDemo</string>
    <string name="remotehello">Hello World,Remote ServiceDemo!</string>
</resources>
ServiceDemo.java
package com.wandroid.servicedemo;

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.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class ServiceDemo extends Activity implements OnClickListener
{   
 private xxxService        mxxxService              = null;
 private IxxxRemoteService mxxxRemoteService        = null;
 private TextView          mTextView                = null;
 private TextView          mremoteTextView           = null;
 private Button            startServiceButton       = null;
 private Button            stopServiceButton         = null;
 private Button            bindServiceButton        = null;
 private Button            unbindServiceButton       = null;
 private Context           mContext                  = null;
 private Button            remotebindServiceButton   = null;
 private Button            remoteunbindServiceButton = null;
 private Button            musicbroadcastButton      = null;
 
 //ServiceConnection在bind時建立連線
 private ServiceConnection mServiceConnection = new ServiceConnection() 
 { 
  public void onServiceConnected(ComponentName name, IBinder service) 
  {
   if( name.getClassName().compareTo
                            ("com.wandroid.servicedemo.xxxService") == 0 )
   {
       //===local service
       mxxxService = ((xxxService.xxxBinder)service).getService();
       try {
     mTextView.setText("I am frome Service :"+                 
                                              Integer.toString(mxxxService.sum(5, 5)));
       } catch (RemoteException e) {
     e.printStackTrace();
       }
   }
   else
   {
       //===remote service
              mxxxRemoteService =  IxxxRemoteService.Stub.asInterface(service);
       try {
    mremoteTextView.setText("I am frome remote Service :"+
                                     Integer.toString(mxxxRemoteService.sumabc(5, 5, 5)));    
       } catch (RemoteException e) {
            e.printStackTrace();
       }
   }
  }
  
  public void onServiceDisconnected(ComponentName name) 
  {
   if(mxxxService != null)
   {
       mxxxService = null;
   }
   else
   {
       mxxxRemoteService = null;
   }
  }
 };
//activity=======   
 public void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
     
            mContext              = ServiceDemo.this;
         mTextView             = (TextView)findViewById(R.id.text);
         mremoteTextView       = (TextView)findViewById(R.id.remotetext);
         startServiceButton    = (Button)findViewById(R.id.startservice);
         stopServiceButton     = (Button)findViewById(R.id.stopservice);
         bindServiceButton     = (Button)findViewById(R.id.bindservice);
         unbindServiceButton   = (Button)findViewById(R.id.unbindservice);
         remotebindServiceButton   = (Button)findViewById(R.id.remotebindservice);
         remoteunbindServiceButton = (Button)findViewById(R.id.remoteunbindservice);
         musicbroadcastButton      = (Button)findViewById(R.id.musicbroadcast);
          
         startServiceButton.setOnClickListener(this);
         stopServiceButton.setOnClickListener(this);
         bindServiceButton.setOnClickListener(this);
         unbindServiceButton.setOnClickListener(this);
         remotebindServiceButton.setOnClickListener(this);
         remoteunbindServiceButton.setOnClickListener(this);
         musicbroadcastButton.setOnClickListener(this);
        }
   
 public void onClick(View v) 
 {
  if(v == startServiceButton)
  {
   Intent i  = new Intent();
   i.setClass(ServiceDemo.this, xxxService.class);
   mContext.startService(i);
  }
  else if(v == stopServiceButton)
  {
   Intent i  = new Intent();
   i.setClass(ServiceDemo.this, xxxService.class);
   mContext.stopService(i);
  }
  else if(v == bindServiceButton)
  {
   Intent i  = new Intent();
   i.setClass(ServiceDemo.this, xxxService.class);
   mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);
  }
  else if(v == unbindServiceButton)
  {
   if( mServiceConnection != null)
   {
       mContext.unbindService(mServiceConnection);
   }
  }
  else if(v == remotebindServiceButton)
  {
   Intent i  = new Intent();
   i.setClass(ServiceDemo.this, xxxRemoteService.class);
   mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);
  }
  else if(v == remoteunbindServiceButton)
  {
   if( mServiceConnection != null)
   {
       mContext.unbindService(mServiceConnection);
       mremoteTextView.setText("");
   }
  }
  else if(v == musicbroadcastButton)
  {
    Intent i  = new Intent();
    i.setAction("com.wandroid.servicedemo.Play_MUSIC");
    sendBroadcast(i);
  }
 }  
}
xxxService.java
package com.wandroid.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class xxxService extends Service 
{
 private static final String TAG = "xxxService";
 
 //bindService()時,建立connection用
 public class xxxBinder extends Binder
 {
     xxxService getService()
     {
  Log.e(TAG, "===getService()===");
  return xxxService.this;
     }
 }

 private xxxBinder mxxxBinder = new xxxBinder();
 
 @Override
 public IBinder onBind(Intent intent) 
        {
  Log.e(TAG, "===onBind===");
  return mxxxBinder;
 }

 @Override
 public boolean onUnbind(Intent intent) 
        {
  Log.e(TAG, "===onUnbind===");
  return super.onUnbind(intent);
 }

//===由startService啟動只會用到以下三個 
 @Override
 public void onCreate() 
        {
  Log.e(TAG, "===onCreate===");
  super.onCreate();
 }
 
 //由bindService啟動,就沒有onStart()
 @Override
 public void onStart(Intent intent, int startId) 
        {
  Log.e(TAG, "===onStart===");
  super.onStart(intent, startId); 
 }
 
 @Override
 public void onDestroy() 
        {
  Log.e(TAG, "===onDestroy===");
  super.onDestroy();
 } 
//service function==== 
 public int sum(int a, int b) throws RemoteException 
 {
  Log.e(TAG, "===sum()===");
  return a+b;
        }
}
xxxRemoteService.java
package com.wandroid.servicedemo;

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

public class xxxRemoteService extends Service 
{
 private static final String TAG = "xxxRemoteService";
 private MediaPlayer  mp         = null;
 
 private final IxxxRemoteService.Stub binder= new IxxxRemoteService.Stub()
 {    
            public int sumabc(int a, int b, int c) throws RemoteException 
     {
  Log.e(TAG, "===remote sumabc()===");
                mp = MediaPlayer.create(xxxRemoteService.this, R.raw.music);
                mp.start();
  return a+b+c;
            }
 };
 
 @Override
 public IBinder onBind(Intent arg0) 
 {
     Log.e(TAG, "===remote onBind()===");
            return this.binder; 
 }
 
 @Override
 public boolean onUnbind(Intent intent) 
        {
     Log.e(TAG, "===remote onUnbind()===");
     mp.stop();  
     return super.onUnbind(intent);
 }

//===由startService啟動只會用到以下三個 
 @Override
 public void onCreate() 
        {
     Log.e(TAG, "===remote onCreate()===");
     super.onCreate();
 }
 
 //由bindService啟動,就沒有onStart()
 @Override
 public void onStart(Intent intent, int startId) 
        {
  Log.e(TAG, "===remote onStart()===");
  super.onStart(intent, startId); 
 }
 
 @Override
 public void onDestroy() 
        {
  Log.e(TAG, "===remote onDestroy()===");
  mp.release();
  super.onDestroy();
 } 
}
IxxxRemoteService.aidl
package com.wandroid.servicedemo;

interface IxxxRemoteService 
{
   int sumabc(int a, int b,int c);
}
xxxBroadcastReceiver.java
package com.wandroid.servicedemo; 
  
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
  
public class xxxBroadcastReceiver extends BroadcastReceiver 
{ 
    private static final String TAG = "xxxBroadcastReceiver";
  
    private IxxxRemoteService mxxxRemoteService = null;
  
    private ServiceConnection mServiceConnection = new ServiceConnection() 
    { 
 public void onServiceConnected(ComponentName name, IBinder service) 
 {
     mxxxRemoteService =  IxxxRemoteService.Stub.asInterface(service);
     try {
  mxxxRemoteService.sumabc(5, 5, 5);    
     } 
            catch (RemoteException e) 
            {
         e.printStackTrace();
            }
 }
   
 public void onServiceDisconnected(ComponentName name) 
 {
     mxxxRemoteService = null;
 }
    };
  
    @Override
    public void onReceive(Context context, Intent intent) 
    {
 Log.e(TAG, "===onReceive()===");
 if(intent.getAction().equals("com.wandroid.servicedemo.Play_MUSIC"))
 {
     Intent i  = new Intent();
     //i.setClass(context, xxxRemoteService.class);
     //context.bindService(i, mServiceConnection, BIND_AUTO_CREATE);
     i.setClass(context, xxxService.class);
     context.startService(i);
 }
    }
}

沒有留言:

張貼留言