尝试使用Intents发送二进制内容时的TransactionTooLargeException

时间:2016-09-07 22:33:22

标签: android android-intent

我需要将二进制内容从我的应用程序发送到设备中打开该文件类型的任何应用程序。

我正在遵循这些说明: https://developer.android.com/training/sharing/send.html#send-binary-content

这是我的代码:

final FileType fileType
final File file;

final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(AncestryApplication.getAppContext(), AncestryApplication.getAppContext().getApplicationContext().getPackageName() + ".provider", file));

intent.setType(fileType.getMimeType());
startActivity(intent);

一些事情:

  1. 如果我将意图操作从ACTION_VIEW更改为ACTION_SEND,我会得到错误的应用列表以打开我的文件
  2. ACTION_SEND似乎有效,但只有小文件大小
  3. intent.setDataAndType()似乎在OS M及更低版本的设备上正常工作。在N我得到相同的TransactionTooLargeException
  4. 最后,这是我需要完成的任务:

    • 我已保存文件,并存储在file:///storage/emulated/0/Download/TempFile.html
    • 由于文件可能太大,我需要将文件的位置发送到第三方应用程序(如adobe pdf reader)以打开文件
    • 没有问题M或更低,很多问题N

    关于我可能做错的任何想法?我一直试图解决这个问题几天,我已经阅读了大量的教程和SO建议,没有任何最终答案。

    感谢。

    编辑:这是我的stacktrace:

    AndroidRuntime: FATAL EXCEPTION: main
    Process: com.myapp.android.apps.myapp, PID: 26785
    java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 27943540 bytes
      at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3752)
      at android.os.Handler.handleCallback(Handler.java:751)
      at android.os.Handler.dispatchMessage(Handler.java:95)
      at android.os.Looper.loop(Looper.java:154)
      at android.app.ActivityThread.main(ActivityThread.java:6077)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
    
    Caused by: android.os.TransactionTooLargeException: data parcel size 27943540 bytes
      at android.os.BinderProxy.transactNative(Native Method)
      at android.os.BinderProxy.transact(Binder.java:615)
      at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3606)
      at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3744)
      at android.os.Handler.handleCallback(Handler.java:751) 
      at android.os.Handler.dispatchMessage(Handler.java:95) 
      at android.os.Looper.loop(Looper.java:154) 
      at android.app.ActivityThread.main(ActivityThread.java:6077) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
    

    编辑2:从基本片段添加了onSaveInstanceState()代码:

    @Override
    public void onSaveInstanceState(final Bundle outState) {
        mSaveInstanceStateCalled = true;
        outState.putBoolean(KEY_PROCESSING_SAVE, mSaveInProgress);
    }
    

1 个答案:

答案 0 :(得分:7)

您发布的logcat中的异常是由于将过多数据打包到由Bundle处理的onSaveInstanceState中而引起的。

如果构建版本为N或更高版本,以下是来自Android源代码的method

private static class StopInfo implements Runnable {
    ActivityClientRecord activity;
    Bundle state;
    PersistableBundle persistentState;
    CharSequence description;
    @Override public void run() {
        // Tell activity manager we have been stopped.
        try {
            if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
            ActivityManagerNative.getDefault().activityStopped(
                activity.token, state, persistentState, description);
        } catch (RemoteException ex) {
            if (ex instanceof TransactionTooLargeException
                    && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
                Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
                return;
            }
            throw ex.rethrowFromSystemServer(); // <<-- exception thrown here
        }
    }
}

我以答案的形式发布此内容,因为评论时间过长。这并不是对问题的完整答案,因为问题中没有足够的信息来回答它。