Android (服务Service)

Android 中有几个重要的组件,其中之一就是Service,这是没有UI的组件,可以做为后台的服务,当然可以使用Intent来启动。同时也可以绑定到宿主对象(调用者,常是Activity)来使用,
注意:
一,Android中的Service与调用者在同一线程,所以要是耗时的操作要在Service中新开线程。
二,Android的Service中,主要是实现其onCreate,onStart, onDestroy,onBind,onUnBind几个函数,来实现我们所需要的功能。

简单的调用:
     简单的调可以在调用者对象中使用Context.startService来调用,以Intent为参数,当然,Intent搜索,匹配目标的方式与以前在《Intent使用》中方式一样。
 下面来看一段例程:

一,声明Service子类

public class TestService extends Service {

 @Override
 public void onCreate() {
  // TODO Auto-generated method stub
  super.onCreate();
  Toast.makeText(this, "Service Created!", Toast.LENGTH_SHORT).show();
 }

 @Override
 public void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();
  Toast.makeText(this, "Service Destroyed!", Toast.LENGTH_LONG).show();
 }

 @Override
 public void onStart(Intent intent, int startId) {
  // TODO Auto-generated method stub
  super.onStart(intent, startId);
  Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
 }

 @Override
 public boolean onUnbind(Intent intent) {
  // TODO Auto-generated method stub
  super.onUnbind(intent);
  Toast.makeText(this, "Service unBind!", Toast.LENGTH_LONG).show();
  return true;
 }

 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  Toast.makeText(this, "Service Bound!", Toast.LENGTH_LONG).show();
  return null;
 }

}

在Manifest.xml中配置此Service.
....
<service android:label="@string/hello" android:name="TestService">
<intent-filter>
<action android:name="start_service"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</service>
....
创建调用者类:

mport android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class HelloActivity extends Activity { 
 
 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // TODO Auto-generated method stub
  super.onCreateOptionsMenu(menu);
  menu.add(0, Menu.FIRST+1, 1, R.string.menu_open);
  menu.add(0, Menu.FIRST+2, 2, "StartService");
  menu.add(0, Menu.FIRST+3, 3, "StopService");
  menu.add(0, Menu.FIRST+4, 4, R.string.menu_close);
  return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // TODO Auto-generated method stub
  super.onOptionsItemSelected(item);
  switch(item.getItemId())
  {
  case Menu.FIRST + 1:
  {
   this.setTitle("Switch Activity");
   Intent i = new Intent();   
   i.setAction("test_action");  
   if (Tools.isIntentAvailable(this,i))
    this.startActivity(i);
   else
    this.setTitle("the Intent is unavailable!!!");
   break;
  }
  case Menu.FIRST + 2:
  {
   this.setTitle("Start Service");
   //Intent i = new Intent(this, TestService.class);
   Intent i = new Intent();
   i.setAction("start_service");
   this.startService(i);
   break;
  }
  case Menu.FIRST + 3:
  {
   this.setTitle("Stop Service");
   Intent i = new Intent(this, TestService.class);
   this.stopService(i);
   break;
  }
  case Menu.FIRST + 4:
  {
   this.setTitle("Close Text!");
   break;
  }
  }
  return true;
 }

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);      
        this.setContentView(R.layout.main);  
    }
}

注意:在操作Service时,我使用了两种Intent方式,一种是显示的直接写TestService.class,此方法只能操作当前应用程序中的Service,一种是隐式的,可以根据Manifest.xml操作不同进程中的Service.

绑定的使用方法:
一,声明一个Service接口,这个提供功能给调用者。

package test.pHello;

public interface ITestService {
 public void showName();

}


二,定义Service,实现了onBind 函数,并返回一个ITestService的实现对象。

package test.pHello;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;

public class TestService extends Service {
    public class Test extends Binder implements ITestService
    {
     private Context mContext = null;
  public void showName() {
         Toast.makeText(mContext, "MyName is TestService", Toast.LENGTH_LONG).show();   
  }  
        public void setContext(Context c){mContext = c;}; 
    }
    Test mTestImplement = new Test();
 @Override
 public void onCreate() {
  // TODO Auto-generated method stub
  super.onCreate();
  Toast.makeText(this, "Service Created!", Toast.LENGTH_SHORT).show();
 }

 @Override
 public void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();
  Toast.makeText(this, "Service Destroyed!", Toast.LENGTH_LONG).show();
 }

 @Override
 public void onStart(Intent intent, int startId) {
  // TODO Auto-generated method stub
  super.onStart(intent, startId);
  Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
 }

 @Override
 public boolean onUnbind(Intent intent) {
  // TODO Auto-generated method stub
  super.onUnbind(intent);
  Toast.makeText(this, "Service unBind!", Toast.LENGTH_LONG).show();
  return true;
 }

 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  mTestImplement.setContext(this);
  Toast.makeText(this, "Service Bound!", Toast.LENGTH_LONG).show();
  return mTestImplement;
 }

}

三,在调用者方面,进行绑定,取得ITestService接口引用。

package test.pHello;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class HelloActivity extends Activity { 
 
 ITestService mService = null;
 ServiceConnection sconnection = new ServiceConnection()
 {
  public void onServiceConnected(ComponentName name, IBinder service)
  {
   mService  = (ITestService)service;
   if (mService != null)
   {
    mService.showName();
   }
  }

  public void onServiceDisconnected(ComponentName name)
  {   
   
  }
 };
 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // TODO Auto-generated method stub
  super.onCreateOptionsMenu(menu);
  menu.add(0, Menu.FIRST+1, 1, "OpenActivity");
  menu.add(0, Menu.FIRST+2, 2, "StartService");
  menu.add(0, Menu.FIRST+3, 3, "StopService");
  menu.add(0, Menu.FIRST+4, 4, "BindService");
  return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // TODO Auto-generated method stub
  super.onOptionsItemSelected(item);
  switch(item.getItemId())
  {
  case Menu.FIRST + 1:
  {
   this.setTitle("Switch Activity");
   Intent i = new Intent();   
   i.setAction("test_action");  
   if (Tools.isIntentAvailable(this,i))
    this.startActivity(i);
   else
    this.setTitle("the Intent is unavailable!!!");
   break;
  }
  case Menu.FIRST + 2:
  {
   this.setTitle("Start Service");
   //Intent i = new Intent(this, TestService.class);
   Intent i = new Intent();
   i.setAction("start_service");
   this.startService(i);
   break;
  }
  case Menu.FIRST + 3:
  {
   this.setTitle("Stop Service");
   Intent i = new Intent(this, TestService.class);
   this.stopService(i);
   break;
  }
  case Menu.FIRST + 4:
  {
   this.setTitle("Bind Service!");
   Intent i = new Intent(this, TestService.class);
   this.bindService(i, this.sconnection, Context.BIND_AUTO_CREATE);
   
   break;
  }
  }
  return true;
 }

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);      
        this.setContentView(R.layout.main);  
    }
}

编译执行,你会发现,是先执行onCreate,然后再执行onBind,在调用者的Context.bindService返回时,ServiceConnection的OnConnected并没有马上被执行。
远程绑定:
上述绑定是在调用者与Service在同一个应用程序中的情况,如果分处在不同的程序中,那么,调用方式又是一另一种情况。我们来看一下。





posted @ 2009-07-24 18:41  岁月无声  阅读(6720)  评论(0编辑  收藏  举报