Android Service远程启动

Android Service远程启动

远程start:

AIDL1代码
  1. manifest:(重点在permission后台权限和exported)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AIDL1"
        tools:targetApi="31">
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>
  1. MyService
public class MyService extends Service {
    public MyService() {
    }

    @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();
        Log.i("yishiqi", "oncreate(i); ");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("yishiqi", "ondestroy(i); ");
    }
}
AIDL2代码
  1. manifest(重点在queries,指定可以访问的包路径)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <queries>
        <package android:name="com.example.aidl1" />
    </queries>
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AIDL2"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
  1. activity(重点在 直接使用包名+类全路径名启动)
package com.example.aidl2;

import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity {
    Intent i;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        Button button1 = findViewById(R.id.button1);
        Button button2 = findViewById(R.id.button2);
        i = new Intent();
        i.setComponent(new ComponentName("com.example.aidl1", "com.example.aidl1.MyService"));
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("yishiqi", "startService(i); ");
                startService(i);
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                stopService(i);
            }
        });
    }
}

远程AIDL绑定以及调用

AIDL1
  1. aidl
// MyAidlText.aidl
package com.example.aidl;

// Declare any non-default types here with import statements

interface MyAidlText {
    /**
     * 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 data);
}
  1. MyService
package com.example.aidl1;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.example.aidl.MyAidlText;

public class MyService extends Service {
    public MyService() {
    }

    boolean tar = false;
    String data = "hello world";

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

            }
            @Override
            public void setData(String data) throws RemoteException {
                MyService.this.data = data;
            }
        };
    }

    @Override
    public void onCreate() {
        super.onCreate();
        tar = true;
        Log.i("yishiqi", "oncreate(i); ");
        new Thread(new Runnable() {
            @Override
            public void run() {

                while (tar) {
                    try {
                        Thread.sleep(1000);
                        Log.i("yishiqi", data);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }).start();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("yishiqi", "ondestroy(i); ");
        tar = false;
    }
}
AIDL2

1.activity

package com.example.aidl2;

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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.example.aidl.MyAidlText;

public class MainActivity extends AppCompatActivity {
    Intent i;
    MyAidlText myAidlText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        Button button1 = findViewById(R.id.button1);
        Button button2 = findViewById(R.id.button2);
        Button button3 = findViewById(R.id.button3);
        EditText editText = findViewById(R.id.editText);
        i = new Intent();
        i.setComponent(new ComponentName("com.example.aidl1", "com.example.aidl1.MyService"));
        ServiceConnection serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                myAidlText = MyAidlText.Stub.asInterface(service);
                Log.i("yishiqi", "onServiceConnected(name, service); ");
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.i("yishiqi", "onServiceDisconnected(name); ");
            }
        };
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("yishiqi", "startService(i); ");
                bindService(i, serviceConnection, BIND_AUTO_CREATE);
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                unbindService(serviceConnection);
            }
        });
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String str = editText.getText().toString();

                try {
                    myAidlText.setData(str);
                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }
}

注意点

  1. AIDL文件中接口顺序不同,调用失败
  2. 前面的接口没有,调用失败
  3. 前面的不同,调用成功

小结论,通过index进行查找匹配调用

  1. 在项目添加新的需求后,要保证新接口在后面,不改变原来的接口顺序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值