欢迎光临
我们一直在努力

Android 多进程开发 - FileDescriptor、Uri、AIDL 接口定义不能抛出异常

FileDescriptor

1、AIDL
  • IMyAidlInterface.aidl,这里是位于 src/main/java/com/my/common 包下

package com.my.common;

import android.os.ParcelFileDescriptor;

interface IMyAidlInterface {
ParcelFileDescriptor getFileDescriptor();
void setFileDescriptor(in ParcelFileDescriptor parcelFileDescriptor);
}

2、Server

private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {

@Override
public ParcelFileDescriptor getFileDescriptor() throws RemoteException {
File filesDir = getFilesDir();
File file = new File(filesDir, "shared_file.dat");

// 如果示例文件不存在,则创建,并写入一些数据
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write("server content".getBytes());
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

try {
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}

@Override
public void setFileDescriptor(ParcelFileDescriptor parcelFileDescriptor) throws RemoteException {
if (parcelFileDescriptor != null) {
try (FileInputStream fileInputStream = new FileInputStream(parcelFileDescriptor.getFileDescriptor())) {
byte[] content = new byte[fileInputStream.available()];
int read = fileInputStream.read(content);
Log.i(TAG, "read " + read + " bytes from file");
Log.i(TAG, "file content: " + new String(content));
} catch (IOException e) {
Log.i(TAG, "open file error: " + e.getMessage());
} finally {
try {
parcelFileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};

3、Client
  • 调用 getFileDescriptor 方法
  • try {
    ParcelFileDescriptor parcelFileDescriptor = myAidlInterface.getFileDescriptor();
    Log.i(TAG, "getFileDescriptor method success");

    if (parcelFileDescriptor != null) {
    try (FileInputStream fileInputStream = new FileInputStream(parcelFileDescriptor.getFileDescriptor())) {
    byte[] content = new byte[fileInputStream.available()];
    int read = fileInputStream.read(content);
    Log.i(TAG, "read " + read + " bytes from file");
    Log.i(TAG, "file content: " + new String(content));
    } catch (IOException e) {
    Log.i(TAG, "open file error: " + e.getMessage());
    } finally {
    try {
    parcelFileDescriptor.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    } catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "getFileDescriptor method error: " + e.getMessage());
    }

  • 调用 setFileDescriptor 方法
  • File filesDir = getFilesDir();
    File file = new File(filesDir, "shared_file.dat");

    // 如果示例文件不存在,则创建,并写入一些数据
    if (!file.exists()) {
    try {
    file.createNewFile();
    } catch (IOException e) {
    e.printStackTrace();
    }
    try {
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    fileOutputStream.write("client content".getBytes());
    fileOutputStream.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    try {
    ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
    try {
    myAidlInterface.setFileDescriptor(parcelFileDescriptor);
    Log.i(TAG, "setFileDescriptor method success");
    } catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "setFileDescriptor method error: " + e.getMessage());
    }
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }

    4、Test
  • 调用 getFileDescriptor 方法,输出结果如下
  • getFileDescriptor method success
    read 14 bytes from file
    file content: server content

  • 调用 setFileDescriptor 方法,输出结果如下
  • read 14 bytes from file
    file content: client content
    setFileDescriptor method success


    Uri

    1、AIDL
    • IMyAidlInterface.aidl,这里是位于 src/main/java/com/my/common 包下

    package com.my.common;

    import android.net.Uri;

    interface IMyAidlInterface {
    Uri getUri();
    void setUri(in Uri uri);
    }

    2、Server

    private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {

    @Override
    public Uri getUri() throws RemoteException {
    File filesDir = getFilesDir();
    File file = new File(filesDir, "shared_file.dat");

    // 如果示例文件不存在,则创建,并写入一些数据
    if (!file.exists()) {
    try {
    file.createNewFile();
    } catch (IOException e) {
    e.printStackTrace();
    }
    try {
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    fileOutputStream.write("server content".getBytes());
    fileOutputStream.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    Uri uri = FileProvider.getUriForFile(ServerService.this, getApplicationContext().getPackageName() + ".fileprovider", file);

    // 授予临时权限
    // 第一个参数是客户端应用包名
    grantUriPermission("com.my.client", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

    return uri;
    }

    @Override
    public void setUri(Uri uri) throws RemoteException {
    if (uri != null) {
    try (InputStream inputStream = getContentResolver().openInputStream(uri)) {
    byte[] content = new byte[inputStream.available()];
    int read = inputStream.read(content);
    Log.i(TAG, "read " + read + " bytes from uri");
    Log.i(TAG, "uri content: " + new String(content));
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    };

    3、Client
  • 调用 getUri 方法
  • try {
    Uri uri = myAidlInterface.getUri();
    Log.i(TAG, "getUri method success");

    if (uri != null) {
    try (InputStream inputStream = getContentResolver().openInputStream(uri)) {
    byte[] content = new byte[inputStream.available()];
    int read = inputStream.read(content);
    Log.i(TAG, "read " + read + " bytes from uri");
    Log.i(TAG, "uri content: " + new String(content));
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    } catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "getUri method error: " + e.getMessage());
    }

  • 调用 setUri 方法
  • File filesDir = getFilesDir();
    File file = new File(filesDir, "shared_file.dat");

    // 如果示例文件不存在,则创建,并写入一些数据
    if (!file.exists()) {
    try {
    file.createNewFile();
    } catch (IOException e) {
    e.printStackTrace();
    }
    try {
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    fileOutputStream.write("client content".getBytes());
    fileOutputStream.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file);
    grantUriPermission("com.my.server", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
    try {
    myAidlInterface.setUri(uri);
    Log.i(TAG, "setUri method success");
    } catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "setUri method error: " + e.getMessage());
    }

    4、Test
  • 调用 getUri 方法,输出结果如下
  • getUri method success
    read 14 bytes from uri
    uri content: server content

  • 调用 setUri 方法,输出结果如下
  • read 14 bytes from uri
    uri content: client content
    setUri method success


    AIDL 接口定义不能抛出异常

    • 在 AIDL 接口定义中,方法签名本身不能包含 throws 关键字来声明抛出异常,会导致编译错误

    int add(int a, int b) throws RemoteException;

    # 输出结果

    syntax error, unexpected identifier, expecting '=' or ';'

    oneway void doSomething() throws RemoteException;

    # 输出结果

    syntax error, unexpected identifier, expecting '=' or ';'

    • 将光标移动到 throws 关键字上,会出现如下提示信息

    AidlTokenTypes. ASSIGN expected, got 'throws'

    赞(0)
    未经允许不得转载:171主机测评 » Android 多进程开发 - FileDescriptor、Uri、AIDL 接口定义不能抛出异常
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址