1.Service不是一个单独的进程,它和它的应用程序在同一个进程中
2.Service不是一个线程,这样就意味着我们应该避免在Service中进行耗时操作
话不多说,我们直接上代码,是bingService启动service的,startService暂时先不上了。。。。。通过bindservice可以使service和avtivity通信。。。
首先创建一个TestServiceOne继承Service;
public class TestServiceOne extends Service {
private static final String TAG = "TestServiceOne";
private int count;
private boolean quit;
private MyBinder binder = new MyBinder();
public class MyBinder extends Binder{
public int getCount(){
return count;
}
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind方法被调用!");
return binder;
}
@Override
public void onCreate(){
super.onCreate();
Log.i(TAG, "onCreate方法被调用!");
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (!quit){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
});
thread.start();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
return super.onStartCommand(intent,flags,startId);
}
public boolean onUnBind(Intent intent){
Log.i(TAG, "onUnbind方法被调用!");
return super.onUnbind(intent);
}
@Override
public void onDestroy(){
this.quit=true;
super.onDestroy();
Log.i(TAG, "onDestroyed方法被调用!");
}
}
public class Main6Activity extends AppCompatActivity {
private Button button1;
private Button button2;
private Button button3;
TestServiceOne.MyBinder binder;
private ServiceConnection conn = new ServiceConnection() {
//activity和service连接成功时回调该方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (TestServiceOne.MyBinder)service;
}
//activity和service断开连接时回调该方法
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main6);
button1 = (Button) findViewById(R.id.bangding);
button2 = (Button) findViewById(R.id.jiechubangding);
button3 = (Button) findViewById(R.id.status);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Main6Activity.this,TestServiceOne.class);
bindService(intent,conn,Service.BIND_AUTO_CREATE);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(conn);
}
});
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("TestServiceOne",binder.getCount()+"");
}
});
}
}
这三个按钮都是普通的按钮,通过按钮可以看打印的log.
总结:Step 1:在自定义的Service中继承Binder,实现自己的IBinder对象
Step 2:通过onBind( )方法返回自己的IBinder对象
Step 3:在绑定该Service的类中定义一个ServiceConnection对象,重写两个方法, onServiceConnected和onDisconnected!然后直接读取IBinder传递过来的参数即可!
下面是AIDL的例子:
AIDL(Android接口描述语言)是一个IDL语言,它可以生成一段代码,可以是一个在Android设备上运行的两个进程使用内部通信进程进行交互。用于不同的进程交互
第一步:在main文件夹下面创建一个aidl的文件夹,在创建一个包名。我这里使用的是com.example.zhujunxian.contentprivodertest 在这个包下面创建一个DIAL文件 名字是IPerson,然后我们把里面的代码改成这样。
// IPerson.aidl
package com.example.zhujunxian.contentprivodertest;
// Declare any non-default types here with import statements
interface IPerson {
int add(int arg1, int arg2);
}
然后我们编译一下 Ctrl+F9 这时候我们在build/generated/source/aidl/debug/com.example.zhujunxian.contentprivodertest下面就会生成一个同样的IPerson,如图:
这个目录下面主要是自动生成的。。。
然后我们自己写一个Myservice继承Service,代码如下
public class MyService extends Service {
IPerson.Stub mStub = new IPerson.Stub() {
@Override
public int add(int arg1, int arg2) throws RemoteException {
return arg1 + arg2;
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mStub;
}
}
这里主要就是自己定义一个两个参数相加的方法。。。
我们在清单文件里面加上
然后我们在重新创建一个项目,用于模仿另一个进程。。。项目名字是MyAidlDemoCustomer,然后把我们刚才那个项目main目录下面的aidl文件夹直接复制到我们新建的这个项目上。。。有一点,我们的报名必须都得是一样的。。。
然后我们创建一个Activity测试。。
public class MainActivity extends AppCompatActivity {
TextView textView;
IPerson mSub;
private static final String TAG = "MainActivitya";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.tv);
Intent intent = new Intent();
intent.setAction("co.example.leo.myService");
intent.setPackage("com.example.zhujunxian.contentprivodertest");
bindService(intent, connection, BIND_AUTO_CREATE);
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mSub = IPerson.Stub.asInterface(service);
if (mSub == null) {
Log.i(TAG, "onServiceConnected: ");
} else {
try {
int value = mSub.add(2, 8);
textView.setText(value + "");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
//解绑服务
super.onDestroy();
unbindService(connection);
}
}
然后我们启动这个应用的时候就会直接调用我们另一个应用的方法。。。具体的细节以后补充。。