27、Service

时间:2022-12-30 20:00:50

1服务可以通过startservice的方法 开启。通过stopservice的方法 停止。

服务有一个特点: 只会一次onCreate()方法一旦被创建出来,以后oncreate() 就不会再被执行了,
以后再去开启服务 只会执行onstart()方法,当服务被停止的时候 onDestroy();

2 服务通过bindservice的方法开启
首先 如果服务不存在 就会执行 oncreate() ->onbind()方法
一旦服务绑定成功 以后再去执行 bindsercie() 就不会在重新创建 或者绑定服务了();

如果我们现实的调用unbindservice()的方法 ,首先 on unbind()方法 -> ondestroy() ;
服务只能被解除绑定一次 多次解除绑定服务 程序会出异常.

开启服务 (startservice)
服务一旦开启与调用者没有任何的关系 , 调用着的activity 即便是退出了 也不会影响
后台的service的运行.
在activity里面 不能去调用服务里面的方法 (因为Service是框架new出来的,activity无法获取到该Service的引用).

通过绑定方式开启服务(bindservice)
服务跟调用者不求同生 ,但求同死.
如果调用者(activity)退出了 那他绑定的服务呢 也会跟着退出.

我们可以在activity里面调用服务里面的方法.

利用 serviceSonnection 接口 返回一个ibinder对象 , 拿着ibinder对象获取到服务里面方法的引用(自定义了一个接口信息) 调用服务里面的方法。

一个应用程序 一个进程里面 定义一个IService 的接口来描述方法

如果我们要调用另外一个进程 服务里面的方法 aidl(android interface defination language)

总结流程:

1.要想访问 一个服务里面的方法 我们需要用到 bindservice();
一 创建一个服务 这个服务里面有一个要被调用的方法.
二 定义一个接口IService , 接口里面的抽象方法 就是去调用service里面的方法。 
三 定义一个mybinder对象 extends IBinder对象 实现 我们声明的接口IService, 在onbind
方法里面把mybinder返回回去。
四 在activity里面 通过bindservice的方法开启服务。 
五 创建出来一个我们MyConn 实现 ServiceConnection接口 onserviceConnected的方法。
这个方法会有一个参数 这个参数就是 MyBinder的对象。 
六 把mybinder强制类型转化成 IServcie。
七 调用IService里面的方法。

27、Service

范例:开启、停止、绑定、解除绑定、调用服务里面的方法。

 public interface IService {
public void callMethodInService();
}
 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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; /**
* 通过startservice开启服务的生命周期。
* 利用bindservice调用服务里面的方法。
* @author dr
*/
public class DemoActivity extends Activity implements OnClickListener { Button bt_start, bt_stop;
// 绑定服务 解除绑定服务
Button bt_bind_service, bt_unbind_service;
Button bt_call_service;
Intent intent;
MyConn conn;
IService iService; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); bt_start = (Button) this.findViewById(R.id.button1);
bt_stop = (Button) this.findViewById(R.id.button2);
bt_bind_service = (Button) this.findViewById(R.id.button3);
bt_unbind_service = (Button) this.findViewById(R.id.button4);
bt_call_service = (Button) this.findViewById(R.id.button5);
bt_start.setOnClickListener(this);
bt_stop.setOnClickListener(this);
bt_bind_service.setOnClickListener(this);
bt_unbind_service.setOnClickListener(this);
bt_call_service.setOnClickListener(this);
intent = new Intent(this, MyService.class);
conn = new MyConn();
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1: // 开启服务
startService(intent);
break;
case R.id.button2: // 停止服务
stopService(intent);
break;
case R.id.button3: // 绑定服务
bindService(intent, conn, Context.BIND_AUTO_CREATE);
break;
case R.id.button4: // 解除绑定服务
unbindService(conn);
break;
// 绑定开启
case R.id.button5: // 调用服务里面的方法
iService.callMethodInService();
break;
}
} private class MyConn implements ServiceConnection {
// 绑定一个服务成功的时候 调用 onServiceConnected
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 绑定成功后,会返回这个IBinder对象(MyService中的onBind返回的)。
iService = (IService) service;
} @Override
public void onServiceDisconnected(ComponentName name) { }
} @Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
} }
 import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder; public class MyService extends Service { @Override
public IBinder onBind(Intent intent) {
System.out.println("on bind");
return new MyBinder();
} public class MyBinder extends Binder implements IService {
@Override
public void callMethodInService() {
sayHelloInService();
}
} /**
* 服务里面的一个方法
*/
public void sayHelloInService() {
System.out.println("hello in service");
} @Override
public boolean onUnbind(Intent intent) {
System.out.println("on unbind");
return super.onUnbind(intent);
} @Override
public void onCreate() {
System.out.println("oncreate");
super.onCreate();
} @Override
public void onStart(Intent intent, int startId) {
System.out.println("onstart"); super.onStart(intent, startId);
} @Override
public void onDestroy() {
System.out.println("ondestroy");
super.onDestroy();
}
}

2.要想访问一个远程服务里的方法 需要用到aidl
一 创建一个服务 这个服务里面有一个要被调用的方法.
二 定义一个接口IService , 接口里面的抽象方法 就是去调用service里面的方法。 
把.java的后缀名改成aidl 把接口里面定义的访问权限的修饰符都给删除。
三 定义一个mybinder对象 extends IService.Stub, 在onbind方法里面把mybinder返回回去。
四 在activity里面 通过bindservice的方法开启服务。
五 创建出来一个我们MyConn 实现 ServiceConnection接口 onserviceConnected的方法,这个方法会有一个参数 这个参数就是MyBinder的对象。
六 IService = IService.Stub.asInterface(myBinder)。
七 调用IService的方法。

27、Service

范例:采用aidl访问远程服务里面的方法

 import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException; /**
* 采用aidl访问远程服务里面的方法 --- 远程服务
* 调用着是:callremote Project。
* @author dr
*
*/
public class RemoteService extends Service { @Override
public IBinder onBind(Intent intent) {
return new MyBinder();
} private class MyBinder extends IService.Stub {
@Override
public void callMethodInService() throws RemoteException {
sayHelloInService();
}
} /**
* 服务里面的一个方法
*/
public void sayHelloInService() {
System.out.println("hello in service");
} @Override
public void onCreate() {
System.out.println("remote service oncreate");
super.onCreate();
} }
 // IService.aidl 文件
interface IService {
void callMethodInService();
}
 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.itcast.remoteservice"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<service android:name=".RemoteService" >
<intent-filter >
<action android:name="cn.itcast.remoteservice"/>
</intent-filter>
</service>
</application> </manifest>
 import cn.itcast.remoteservice.IService;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View; /**
* 采用aidl访问远程服务里面的方法 --- 调用远程服务
* 调用着是:remoteservice Project。
* @author dr
*
*/
public class DemoActivity extends Activity {
IService iService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); Intent intent = new Intent();
intent.setAction("cn.itcast.remoteservice");
bindService(intent, new MyConn(), BIND_AUTO_CREATE);
} public void click(View view){
try {
// 调用了远程服务的方法
iService.callMethodInService();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} private class MyConn implements ServiceConnection{ @Override
public void onServiceConnected(ComponentName name, IBinder service) {
iService = IService.Stub.asInterface(service);
} @Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
} }
}
 // 把 远程服务 Demo中的 aidl文件复制过来。包路径要一致。
interface IService {
void callMethodInService();
}
 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.itcast.remoteservice"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<service android:name=".RemoteService" >
<intent-filter >
<action android:name="cn.itcast.remoteservice"/>
</intent-filter>
</service>
</application> </manifest>

范例:采用aidl挂断电话

 import java.lang.reflect.Method;
import com.android.internal.telephony.ITelephony;
import android.app.Activity;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View; /**
* 采用aidl挂断电话
* @author dr
*/
public class DemoActivity extends Activity {
ITelephony iTelephony; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); try {
// 获取系统电话管理的服务
Method method = Class.forName("android.os.ServiceManager")
.getMethod("getService", String.class);
IBinder binder = (IBinder) method.invoke(null,
new Object[] { TELEPHONY_SERVICE });
iTelephony = ITelephony.Stub.asInterface(binder);
} catch (Exception e) {
e.printStackTrace();
}
} public void endcall(View view) {
try {
iTelephony.call("123");
} catch (RemoteException e) {
e.printStackTrace();
}
// iTelephony.call("123");
}
}
 /* //device/java/android/android/content/Intent.aidl
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

// NeighboringCellInfo.aidl
package android.telephony; parcelable NeighboringCellInfo;
 <uses-permission android:name="android.permission.CALL_PHONE" />