Android学习-从另一个App启动本地AppService(1)

本文详细介绍如何在Android系统中实现跨应用服务通信,包括通过Intent启动服务、使用AIDL完成跨应用绑定,以及如何通过远程调用修改服务状态,实现两应用间的实时数据同步。

之前有学习过从另一个App启动本地AppClass,通过Action来完成。
由于Service在android5.0后只能通过显示Intent来启动Service

本地App:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService(new Intent(this,AppService.class));
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopService(new Intent(this,AppService.class));
    }
}

AppService:

public class AppService extends Service {
    public AppService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    Override
    public void onCreate() {
        super.onCreate();
        System.out.println("Service started");
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("Service destoryed");
    }
}

AnotherApp:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Intent serviceIntent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        serviceIntent=new Intent();
        serviceIntent.setComponent(new ComponentName("com.example.nick.startservicefromanotehrapp","com.example.nick.startservicefromanotehrapp.AppService"));
        //通过组件Component输入对应包名及类名启动另一个App中的服务,包名可在MainFest中找到
        findViewById(R.id.btnStartService).setOnClickListener(this);
        findViewById(R.id.btnStopService).setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnStartService:
                startService(serviceIntent);
                break;
            case R.id.btnStopService:
                stopService(serviceIntent);
                break;
        }
    }
}

在此基础上,可以使用新建AIDL页面完成跨应用绑定
在App中新建AIDL,会自动完成代码:

interface IAppServiceRemoteBinder {
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}

同时在AppService中:

  public IBinder onBind(Intent intent) {
      return new IAppServiceRemoteBinder.Stub() {
          @Override
          public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
          }
      };
    }

在新建完按钮后增加findview获取按钮
增加条件触发:

case R.id.btnBinderAppService:
                bindService(serviceIntent,this,Context.BIND_AUTO_CREATE);
                break;
case R.id.btnUnbinderAppService:
                unbindService(this);
                break;

增加connect和disconnect:

    public void onServiceConnected(ComponentName name, IBinder service) {
        System.out.println("Bind Service");
        System.out.println(service);
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
}

通过另一个APP远程操作进行通信
在之前的基础上:
在APP中的AIDL文件中新增:

 void setData(String data);

在AppService中加入:

  public void setData(String data) throws RemoteException {
      AppService.this.data=data;
  }

oncreate下新建线程进行捕获信息

new Thread(){
        @Override
        public void run() {
            super.run();
            running=true;
            while (running){
                System.out.println(data);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();

onDestory下增加boolean开关:

  running=false;

新建开关及初始数据对象

private  String data="默认数据";
private boolean running=false;

在AnotherAPP中新建文本框及同步按钮:

private EditText etInput;
etInput=findViewById(R.id.etInput);
//不在同一个方法中;
findViewById(R.id.btnSync).setOnClickListener(this);

在Switch中:

case R.id.btnSync:
            if (binder!=null){
                try {
                    binder.setData(etInput.getText().toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            break;

在connect及disconnect中:

public void onServiceConnected(ComponentName name, IBinder service) {
        System.out.println("Bind Service");
        System.out.println(service);
        binder=IAppServiceRemoteBinder.Stub.asInterface(service);
        //此处为强制类型转换
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
    private IAppServiceRemoteBinder binder=null;
    }

需要在AnotherAPP中新建AIDL FOLDER文件,并在其下新建名称同APP包名的包文件夹,并将APP中的AIDL文件复制过去

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值