首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android:通过意图发送ParcelFileDescriptor的例外

Android:通过意图发送ParcelFileDescriptor的例外
EN

Stack Overflow用户
提问于 2013-09-09 20:01:37
回答 1查看 3.8K关注 0票数 3

我正在编写一个android应用程序,在该应用程序中,我的服务需要向其他应用程序发送图像(通过广播消息或启动服务--可能有多个有兴趣接收图像的应用程序)。

如果我将图像加载到位图对象中,并将其作为意图的“附加”,它将实际工作。但是,我想看看是否可以发送一个ParcelFileDescrptor,让客户端自己加载Bitmap对象(通过阅读规范,ParcelFileDescriptor看起来就是为了这个目的而创建的--进程间共享文件)。在这里,我试图避免通过意图发送大对象。所以我写了这样的东西:

代码语言:javascript
复制
    @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    System.out.println("Service is called" + this.getClass());
    Intent newIntent = new Intent(MY_ACTION);
    try {
        File icon = new File(getExternalFilesDir(null), "robot_icon.jpg");
        icon.setReadable(true, false);
        if( !icon.exists() ) {
            System.out.println("Writting file " + icon);
                FileOutputStream out;
                out = new FileOutputStream(icon);
                BitmapFactory.decodeResource(getResources(), R.drawable.two_face_answer_map).compress(CompressFormat.JPEG, 100, out);
                out.close();
                System.out.println("Closing file after writing" + icon);
        }

        newIntent.putExtra(EXTRA_BITMAP, ParcelFileDescriptor.open(icon, ParcelFileDescriptor.MODE_READ_WRITE));
//          sendBroadcast(newIntent);
        startService(newIntent);
    } catch (FileNotFoundException e) {
        Log.e(TAG, "Error opening robot icon file", e);
    }catch (IOException e) {
        Log.e(TAG, "Error opening robot icon file", e);
    }

    System.out.println("No Exception");
    return super.onStartCommand(intent, flags, startId);
}

当执行这段代码时,我总是收到一个RuntimeException,上面写着“不允许在这里写文件描述符”。请注意,我看到了sendBroadcast和startService选项的问题。有人知道为什么这里不允许吗?我做错什么了?我是不是误解了ParcelFileDescriptor?这是痕迹:

01-01 :06:02.589: E/AndroidRuntime(7483):致命例外:主01-01 08:06:02.589: E/AndroidRuntime(7483):java.lang.RuntimeException:无法启动服务com.test.robotsample.MyService@4161a0a8意图{cmp=com.test.robotsample/..MyService }:java.lang.RuntimeException:不允许在这里写入文件描述符01-01 08:06:02.589: E/AndroidRuntime(7483):at at01-01 08:06:02.589: E/AndroidRuntime(7483):在android.app.ActivityThread.access$1900(ActivityThread.java:130) 01-01 :08:02.589: E/AndroidRuntime(7483):at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292) 01-01 : 08:06:02.589: E/AndroidRuntime(7483):在android.os.Handler.dispatchMessage(Handler.java:99) 01-01 08:06:02.589: E/AndroidRuntime(在android.app.ActivityThread.main(ActivityThread.java:4745) 01-01 :08:02.589: E/AndroidRuntime(7483):at android.os.Looper.loop 01-01 :06:02.589: E/AndroidRuntime(7483):at java.lang.reflect.Method.invokeNative(原生方法) 01-01 : 08:06:02.589: E/AndroidRuntime(7483):java.lang.reflect.Method.invoke(( com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) ) 01-01 08:06:02.589: E/AndroidRuntime(7483):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 01-01 08:06:02.589: E/AndroidRuntime(7483):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 01-01 08:06:02.589: E/AndroidRuntime(7483):at dalvik.system.NativeStart.main(原生方法) 01-01 08:06:02.589: E/AndroidRuntime(7483):由: java.lang.RuntimeException:不允许在这里写入文件描述符: 01-01 :06:02.589: E/AndroidRuntime(7483):at android.os.Parcel.writeFileDescriptor(Parcel.java:552)方法) 01-01 08:06:02.589: E/AndroidRuntime(7483):at android.os.Parcel.writeFileDescriptor(Parcel.java:552) 01-01 08:06:02.589: E/AndroidRuntime(7483):at android。os.ParcelFileDescriptor.writeToParcel(ParcelFileDescriptor.java:412) 01-01 08:06:02.589: E/AndroidRuntime(7483):android.os.Parcel.writeParcelable(Parcel.java:1254) 01-01 08:06:02.589: E/AndroidRuntime(7483):android.os.Parcel.writeValue(Parcel.java:1173) 01-01 08:06:02.589: E/AndroidRuntime(7483):android.os.Parcel.writeMapInternal(Parcel.java:591) 01-0108:06:02.589: E/AndroidRuntime(7483):在android.os.Bundle.writeToParcel(Bundle.java:1619) 01-01 08:06:02.589: E/AndroidRuntime(7483):android.os.Parcel.writeBundle(Parcel.java:605) 01-01 :06:02.589: E/AndroidRuntime(7483):android.content.Intent.writeToParcel(Intent.java:6470) 01-01 08:06:02.589: E/AndroidRuntime(7483):在android.app.ActivityManagerProxy.startService(ActivityManagerNative.java:2468) 01-01 08:06:02.589: E/AndroidRuntime(7483):android.app.ContextImpl.startService(ContextImpl.java:1149) 01-01 08:06:02.589: E/AndroidRuntime(7483):android.content.ContextWrapper.startService(ContextWrapper.java:383) 01-01 08:06:02.589: 02.589: E/AndroidRuntime(7483):at com.test.robotsample.MyService.onStartCommand(MyService.java:63) 01-01 08:06:02.589: E/AndroidRuntime(7483):在android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2490) 01- 08:06:02.589: E/AndroidRuntime(7483):.

EN

回答 1

Stack Overflow用户

发布于 2014-05-21 06:41:43

是的,通过意图传递ParcelFileDescriptor是不可能的。尽管这一点似乎并没有在Android文档中得到明确的记录。

替代办法:

  • 使用Bundle.putBinder()传递一个绑定器,它将返回一个带有PFD的包(来自API 18)。
  • 使用以Context.bindService()开头的“绑定服务”,在这里您再次获得获得PFD的绑定器。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18706062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档