前言:

在Android系统java层次service介绍已经安卓服务的种类,下面通过实列看如何实现各种服务!

本地服务的实现步骤:

第一步:新建一个Android工程,我这里命名为servicestudy. 第二步:修改activity_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_world"          />      <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"      />  </LinearLayout>  
第三步:创建服务类,命名为MyService.java代码如下:
package com.jalon.servicestudy;import android.app.Service;  import android.content.Intent;  import android.os.Binder;  import android.os.IBinder;  import android.text.format.Time;  import android.util.Log;  public class MyService extends Service {      //定义个一个Tag标签      private static final String TAG = "MyService";      //这里定义吧一个Binder类,用在onBind()有方法里,这样Activity那边可以获取到      private MyBinder mBinder = new MyBinder();      @Override      public IBinder onBind(Intent intent) {          Log.e(TAG, "start IBinder~~~");          return mBinder;      }      @Override      public void onCreate() {          Log.e(TAG, "start onCreate~~~");          super.onCreate();      }            @SuppressWarnings("deprecation")@Override      public void onStart(Intent intent, int startId) {          Log.e(TAG, "start onStart~~~");          super.onStart(intent, startId);       }            @Override      public void onDestroy() {          Log.e(TAG, "start onDestroy~~~");          super.onDestroy();      }                  @Override      public boolean onUnbind(Intent intent) {          Log.e(TAG, "start onUnbind~~~");          return super.onUnbind(intent);      }            //这里我写了一个获取当前时间的函数,不过没有格式化就先这么着吧      public String getSystemTime(){                    Time t = new Time();          t.setToNow();          return t.toString();      }            public class MyBinder extends Binder{          MyService getService()          {              return MyService.this;          }      }  }  

第四步:修改MainActivity.java,通过四个按键分别调用startService,stopService,bindService,unbindService。代码如下:
package com.jalon.servicestudy;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.util.Log;import android.view.View;  import android.view.View.OnClickListener;  import android.widget.Button;  import android.widget.TextView;  public class MainActivity extends Activity implements OnClickListener {           private static final String TAG = "MyService";private MyService  mMyService;      private TextView mTextView;      private Button startServiceButton;      private Button stopServiceButton;      private Button bindServiceButton;      private Button unbindServiceButton;      private Context mContext;            //这里需要用到ServiceConnection在Context.bindService和context.unBindService()里用到      private ServiceConnection mServiceConnection = new ServiceConnection() {          //当我bindService时,让TextView显示MyService里getSystemTime()方法的返回值           public void onServiceConnected(ComponentName name, IBinder service) {              // TODO Auto-generated method stub              mMyService = ((MyService.MyBinder)service).getService();              mTextView.setText("I am frome Service :" + mMyService.getSystemTime());          }                    public void onServiceDisconnected(ComponentName name) {              // TODO Auto-generated method stub                        }      };      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          setupViews();      }            public void setupViews(){                mContext = MainActivity.this;          mTextView = (TextView)findViewById(R.id.text);                       startServiceButton = (Button)findViewById(R.id.startservice);          stopServiceButton = (Button)findViewById(R.id.stopservice);          bindServiceButton = (Button)findViewById(R.id.bindservice);          unbindServiceButton = (Button)findViewById(R.id.unbindservice);                    startServiceButton.setOnClickListener(this);          stopServiceButton.setOnClickListener(this);          bindServiceButton.setOnClickListener(this);          unbindServiceButton.setOnClickListener(this);      }           public void onClick(View v) {     Log.d(TAG,"IN oNClink function!");        // TODO Auto-generated method stub          if(v == startServiceButton){         Log.i(TAG,"startServiceButton pressed!");            Intent i  = new Intent();              i.setClass(MainActivity.this, MyService.class);              mContext.startService(i);                     }else if(v == stopServiceButton){         Log.i(TAG,"stopServiceButton pressed!");            Intent i  = new Intent();              i.setClass(MainActivity.this, MyService.class);              mContext.stopService(i);          }else if(v == bindServiceButton){         Log.i(TAG,"bindServiceButton pressed!");            Intent i  = new Intent();              i.setClass(MainActivity.this, MyService.class);              mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);          }else{         Log.i(TAG,"mServiceConnection button pressed!");            mContext.unbindService(mServiceConnection);          }      }      }  

通过adb 查看MyService的打印: logcat -sMyService
连续按三次startService按键,按三次bindService按键,分别按一次unbindService按键和一次stopService按键。 从打印可以看出一个服务可以多次start,但是onCreate只执行一次,onStart执行多次,服务只能被绑定一次。服务没有被引用后才会调用onDestory接口! 调试出现的问题: 点击按键后服务类MyService没有任何打印是因为没有在AndroidManifest.xml中注册实现的服务。
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.jalon.servicestudy"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="18" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.jalon.servicestudy.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>        <span style="color:#cc0000;"><service android:name=".MyService" android:exported="true"></service>  </span>    </application></manifest>
点击获取源代码

远程服务的实现步骤:

服务端的实现步骤

第一步:新建工程实现AIDL服务,工程名为serviceStudy。 第二步:在eclipse中在工程的src目录中新建一个包com.jalon.aidl 第三步:在新建的aidl包中新建IMyService.aidl文件,代码如下:
package com.jalon.aidl;  import com.jalon.aidl.Student;  interface IMyService {      List<Student> getStudent();      void addStudent(in Student student);  }  
第四步:在aidl包中新建 Student.aidl文件,代码如下:
package com.jalon.aidl;  parcelable Student;  
第五步:在aidl包中新建 Student类,Student.java,代码如下:
package com.jalon.aidl;  import java.util.Locale;  import android.os.Parcel;  import android.os.Parcelable;  public final class Student implements Parcelable {      public static final int SEX_MALE = 1;      public static final int SEX_FEMALE = 2;      public int sno;      public String name;      public int sex;      public int age;      public Student() {      }      public static final Parcelable.Creator<Student> CREATOR = new              Parcelable.Creator<Student>() {                  public Student createFromParcel(Parcel in) {                      return new Student(in);                  }                  public Student[] newArray(int size) {                      return new Student[size];                  }              };      private Student(Parcel in) {          readFromParcel(in);      }      @Override      public int describeContents() {          return 0;      }      @Override      public void writeToParcel(Parcel dest, int flags) {          dest.writeInt(sno);          dest.writeString(name);          dest.writeInt(sex);          dest.writeInt(age);      }      public void readFromParcel(Parcel in) {          sno = in.readInt();          name = in.readString();          sex = in.readInt();          age = in.readInt();      }        @Override      public String toString() {          return String.format(Locale.ENGLISH, "Student[ %d, %s, %d, %d ]", sno, name, sex, age);      }  }  
保存后在gen目录下,com.jalon.aidl包下自动生成IMyService.java类,代码如下:
public interface IMyService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class <span style="color:#ff6600;">Stub</span> extends <span style="color:#3366ff;">android.os.Binder</span> implements <span style="color:#33ccff;">com.jalon.aidl.IMyService</span>{//自动生成的IPC stub子类,只需要服务实现这个stub就可以完成ipc通信private static final java.lang.String DESCRIPTOR = "com.jalon.aidl.IMyService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}....}....}
生成的 IMyService.java如下如所示:
第六步:在com.jalon.aidlstudy包中新建MyService.java实现服务服务。需要集成Service实列话IPC通信stub类。代码如下:
package com.jalon.aidlstudy;import java.util.ArrayList;import java.util.List;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.Parcel;import android.os.RemoteException;import android.util.Log;import com.jalon.aidl.Student;import com.jalon.aidl.IMyService;public class MyService extends Service  {      private final static String TAG = "MyService";      private static final String PACKAGE_SAYHI = "com.jalon.aidlclient";       // private NotificationManager mNotificationManager;      private boolean mCanRun = true;      private List<Student> mStudents = new ArrayList<Student>();            //这里实现了aidl中的抽象函数      private final IMyService.Stub mBinder = new IMyService.Stub() {            @Override          public List<Student> getStudent() throws RemoteException {              synchronized (mStudents) {                  return mStudents;              }          }            @Override          public void addStudent(Student student) throws RemoteException {              synchronized (mStudents) {                  if (!mStudents.contains(student)) {                      mStudents.add(student);                  }              }          }           <span style="color:#009900;"> //在这里可以做权限认证,return false意味着客户端的调用就会失败,比如下面,只允许包名为com.example.test的客户端通过,          //其他apk将无法完成调用过程  </span>        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)                  throws RemoteException {              String packageName = null;              String[] packages = MyService.this.getPackageManager().                      getPackagesForUid(getCallingUid());              if (packages != null && packages.length > 0) {                  packageName = packages[0];              }              Log.i(TAG, "onTransact: " + packageName);              if (!PACKAGE_SAYHI.equals(packageName)) {                  return false;              }                return super.onTransact(code, data, reply, flags);          }        };        @Override      public void onCreate()      {      Log.i(TAG,"in MyService onCreate function!");        Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService");          thr.start();            synchronized (mStudents) {              for (int i = 1; i < 6; i++) {                  Student student = new Student();                  student.name = "student#" + i;                  student.age = i * 5;                  mStudents.add(student);              }          }           // mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);          super.onCreate();      }        @Override      public IBinder onBind(Intent intent)      {          Log.d(TAG, String.format("on bind,intent = %s", intent.toString()));          displayNotificationMessage("服务已启动");          return mBinder;      }        @Override      public int onStartCommand(Intent intent, int flags, int startId)      {          return super.onStartCommand(intent, flags, startId);      }        @Override      public void onDestroy()      {          mCanRun = false;          super.onDestroy();      }        private void displayNotificationMessage(String message)      {     /*        Notification notification = new Notification(R.drawable.icon, message,                  System.currentTimeMillis());          notification.flags = Notification.FLAG_AUTO_CANCEL;          notification.defaults |= Notification.DEFAULT_ALL;          PendingIntent contentIntent = PendingIntent.getActivity(this, 0,                  new Intent(this, MyActivity.class), 0);          notification.setLatestEventInfo(this, "我的通知", message,                  contentIntent);          mNotificationManager.notify(R.id.app_notification_id + 1, notification);  */    }        class ServiceWorker implements Runnable      {          long counter = 0;            @Override          public void run()          {              // do background processing here.....              while (mCanRun)              {                  Log.i(TAG, "" + counter);                  counter++;                  try                  {                      Thread.sleep(2000);                  } catch (InterruptedException e)                  {                      e.printStackTrace();                  }              }          }      }}  
service只想让某个特定的apk使用,而不是所有apk都能使用,这个时候,你需要重写Stub中的onTransact方法,根据调用者的uid来获得其信息,然后做权限认证,如果返回true,则调用成功,否则调用会失败。对于其他apk,你只要在onTransact中返回false就可以让其无法调用IMyService中的方法,这样就可以解决这个问题了。
注意:一定要修改AndroidManifest.xml和实际一致不然,通信是找不到服务的,代码如下:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.jalon.aidlstudy"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="18" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <span style="color:#3333ff;"><service      android:name="com.jalon.aidlstudy.MyService"      android:process=":remote"      android:exported="true" >      <intent-filter>          <category android:name="android.intent.category.DEFAULT" />          <action android:name="com.jalon.aidlstudy.MyService" />      </intent-filter>  </service> </span>    </application></manifest>
在 AndroidManifest.xml 里 Service 元素的常见选项解释如下:
android:name  -------------  服务类名
android:label  --------------  服务的名字,如果此项不设置,那么默认显示的服务名则为类名
android:icon  --------------  服务的图标
android:permission  -------  申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务
android:process  ----------  表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字
android:enabled  ----------  如果此项设置为 true,那么 Service 将会默认被系统启动,不设置默认此项为 false
android:exported  ---------  表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false

客户端的实现步骤

第一步:新建客户端工程,工程名aidlClient 第二步:将上面实现的com.jalon.aidl包拷贝到src目录下,保存刷新eclipse,将会在gen目录下看到生成的IMyService.java。 第三步:实现MainActivity类,代码如下:
package com.jalon.aidlclient;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.app.Activity;import android.app.AlertDialog;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.util.Log;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import com.jalon.aidl.IMyService;import com.jalon.aidl.Student;public class MainActivity extends Activity implements OnClickListener  {private static final String ACTION_BIND_SERVICE = "com.jalon.aidlstudy.MyService"; //必须要和上面AndroidMainfest定义的一致private static final String TAG = "AidlClient";    private IMyService mIMyService;          private ServiceConnection mServiceConnection = new ServiceConnection()      {          @Override          public void onServiceDisconnected(ComponentName name)          {              mIMyService = null;          }            @Override          public void onServiceConnected(ComponentName name, IBinder service)          {          Log.i(TAG," bind to the service  onServiceConnected!");            //通过服务端onBind方法返回的binder对象得到IMyService的实例,得到实例就可以调用它的方法了              mIMyService = IMyService.Stub.asInterface(service);              try {                  Student student = mIMyService.getStudent().get(0);                  showDialog(student.toString());              } catch (RemoteException e) {                  e.printStackTrace();              }            }     };  @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button1 = (Button) findViewById(R.id.button1);          button1.setOnClickListener(this) ;}    public void onClick(View view) {          if (view.getId() == R.id.button1) {         Log.i(TAG,"the button press!");            Intent intentService = new Intent(ACTION_BIND_SERVICE);              intentService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);              MainActivity.this.bindService(intentService, mServiceConnection, BIND_AUTO_CREATE);          }        }        public void showDialog(String message)      {          new AlertDialog.Builder(MainActivity.this)                  .setTitle("scott")                  .setMessage(message)                  .setPositiveButton("确定", null)                  .show();      }     @Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}

遇到的问题:点击后客户端程序崩溃,用logcat *:e,发现是找不到服务类,仔细确认服务类的路径和名字后问题解决! 点击获取源码

安卓系统服务的添加和获取:

java系统的服务都是由ServiceManager来管理的,源代码位于frameworks/base/core/java/android/os/ServiceManager.java.提供了用于管理service的addService和getService等接口。安卓的系统服务都是在frameworks/base/services/java/com/android/server/SystemServer.java 中通过ServiceManager加入到系统中的,比如:
                if(FeatureOption.MTK_BT_SUPPORT)///if MTK_BT_SUPPORT is on                {                Slog.i(TAG, "Bluetooth Manager Service");                <span style="color:#3366ff;">bluetooth = new BluetoothManagerService(context);                ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);</span>                    if (true == FeatureOption.MTK_BT_PROFILE_SPP) {                        //bluetoothSocket = new BluetoothSocketService(context, bluetooth);                        //ServiceManager.addService(BluetoothSocketService.BLUETOOTH_SOCKET_SERVICE,                        //                          bluetoothSocket);            }                                    if (true == FeatureOption.MTK_BT_PROFILE_MANAGER) {                        BluetoothProfileManager = new BluetoothProfileManagerService(context);                        ServiceManager.addService(BluetoothProfileManagerService.BLUETOOTH_PROFILEMANAGER_SERVICE,                                                  BluetoothProfileManager);                    }                }//MTK_BT_SUPPORT            }
将蓝牙相关服务加入到系统。
当服务已经加入ServiceManager后,若后面需要使用服务时,只需要通过ServiceManager获取就可了,列如:
        mHdmiManager = IMtkHdmiManager.Stub.asInterface(ServiceManager                .getService(Context.MTK_HDMI_SERVICE));
MTK平台获取HDMI 的管理服务。

更多相关文章

  1. tcping测试服务器TCP端口
  2. Android打电话过程
  3. Android中OkHttp的使用(详解)
  4. OkHttp学习系列二:谈谈Android中使用的坑
  5. 4 行代码实现 ANDROID 快速文件下载
  6. ART模式下dex2oat出错导致系统无法正常启动
  7. android 加载自定义图片并在图片上绘图
  8. Android中怎么启动关闭Service及功能解释 .
  9. Android(安卓)setBackgroundResource()/setBackgroundDrawable()

随机推荐

  1. 揭秘 Node.js 底层架构
  2. 详解Node模块加载机制
  3. golang 发送post请求 其body中json对象使
  4. 秘籍:自学后端知识体系
  5. python入门教程12-02 (python语法入门之多
  6. android MediaPlayer深入分析
  7. ITIL 4:服务目录管理
  8. 年末最新整理:阿里、腾讯、字节、华为、百
  9. 消息队列为什么说它像漏斗?
  10. 年底报表做到哭泣?学会Excel融合分析,让你