app中有一个MyService的服务。我们需要做的就在anotherapp这个应用程序当中去和MyService做交互。首先是app中的应用程序如下:
MainActivity的程序如下:
package startservicefromanotherapp.lg.com.app;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(MainActivity.this, MyService.class));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
stopService(new Intent(MainActivity.this, MyService.class));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
MyService中的应用程序如下:
package startservicefromanotherapp.lg.com.app;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
/*这个创建的服务器将会被另外的一个应用启动*/
public class MyService extends Service {
private boolean isRunning=false;
private String info = "默认的数据";
public MyService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//MyService.this.info = intent.getStringExtra("data");
return super.onStartCommand(intent, flags, startId);
}
/*使用定义好的AIDL生成一个Binder类型的对象,这个对象实现了AIDL接口中的所有的方法*/
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return new IMyAidlInterface.Stub(){
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
//这个方法的目的是使其他应用中的程序可以改变这个Service内部的内容
@Override
public void setData(String str) throws RemoteException {
MyService.this.info=str;
}
};
}
/*在一个Service中,一般都会重写这俩个的方法*/
@Override
public void onCreate() {
super.onCreate();
Log.v("info-->", "连接到另外一个应用的服务");
System.out.println("连接到另外一个应用的服务");
isRunning=true;
new Thread(){
@Override
public void run() {
while(isRunning) {
Log.v("info-->",info);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("解除另外一个应用的服务");
Log.v("info-->", "解除另外一个应用的服务");
isRunning=false;
}
}
content-main中的内容如下,但是,我并没有做过多的修改:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="startservicefromanotherapp.lg.com.app.MainActivity"
tools:showIn="@layout/activity_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>
还有一个就是我们定义好的AIDL:它的程序的内容如下:
// IMyAidlInterface.aidl
package startservicefromanotherapp.lg.com.app;
// Declare any non-default types here with import statements
/*定义一个安卓接口定义语言,也就是所谓的AIDL.这是要注意的。可以使用它的一个方法生成一个Binder类的对象*/
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
void setData(String str);
}
接下来的是anotherapp中的内容如下:
首先是MainActivity中的程序的内容如下:
package startservicefromanotherapp.lg.com.anotherapp;
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.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import startservicefromanotherapp.lg.com.app.IMyAidlInterface;
public class MainActivity extends AppCompatActivity implements ServiceConnection {
private Intent intent;
private Button startSer;
private Button stopSer;
private Button bindSer;
private Button unbindSer;
private EditText et;
private Button btnSyc;
private IMyAidlInterface myAidlInterface=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
setListener();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
public void init() {
startSer = (Button) findViewById(R.id.startService);
stopSer = (Button) findViewById(R.id.stopService);
bindSer = (Button) findViewById(R.id.bindService);
unbindSer = (Button) findViewById(R.id.unbindService);
btnSyc = (Button) findViewById(R.id.btnSyc);
et = (EditText) findViewById(R.id.et);
intent = new Intent();
intent.setComponent(new ComponentName("startservicefromanotherapp.lg.com.app","startservicefromanotherapp.lg.com.app.MyService"));
}
public void setListener() {
startSer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//intent.putExtra("data", "anotherAppData");
startService(intent);
}
});
stopSer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
});
bindSer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bindService(intent, MainActivity.this, BIND_AUTO_CREATE);
}
});
unbindSer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(MainActivity.this);
}
});
/*同步数据按钮*/
btnSyc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if (myAidlInterface != null) {
myAidlInterface.setData(et.getText().toString());
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("bind Service");
System.out.println(service);
// 注意这个地方是要注意的。这里需要使用的是这个方法。而不是对service进行直接的强制类型转换。
// 这是要注意的。
myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("unbind Service");
}
}
接下来的就是content-main中的程序的内容:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="startservicefromanotherapp.lg.com.anotherapp.MainActivity"
tools:showIn="@layout/activity_main">
<Button
android:id="@+id/startService"
android:text="连接外部的服务"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/stopService"
android:text="断开外部的服务"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bindService"
android:text="绑定外部的服务"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="解除绑定的外部的服务"
android:id="@+id/unbindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:text="这是另外的一个应用的信息"
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnSyc"
android:text="同步数据"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
再接下来的就是AIDL接口中的程序的内容了。这个内容和上面的app中的AIDL中的内容是一模一样的。
// IMyAidlInterface.aidl
package startservicefromanotherapp.lg.com.app;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
void setData(String str);
}
我们可以来看一下anotherapp中的界面布局是如下的:
这个就是使用AIDL来操作的整个 的流程。