AndroidRuntime:致命异常:主进程数据包大小1245464字节错误

时间:2019-06-02 03:11:32

标签: java android

由于图像大小,我可能会遇到错误,但是我没有太多的代码知识。如何修复下面的源代码?

由于图像大小,我可能会遇到错误,但是我没有太多的代码知识。如何修复下面的源代码?

================================================ =========================

Logcat错误消息:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: im.r_c.android.puz, PID: 18376

java.lang.RuntimeException: 
android.os.TransactionTooLargeException: data parcel size 1245464 
bytes
    at android.app.ActivityThread$StopInfo.run(ActivityThread.java:4006)
    at android.os.Handler.handleCallback(Handler.java:789)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
 Caused by: android.os.TransactionTooLargeException: data parcel size 1245464 bytes
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(Binder.java:748)
    at android.app.IActivityManager$Stub$Proxy.activityStopped(IActivityManager.java:4636)
    at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3998)
    at android.os.Handler.handleCallback(Handler.java:789) 
    at android.os.Handler.dispatchMessage(Handler.java:98) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6541) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

================================================ ========================

这是一款益智游戏App.two Activity全部源代码

GameActivity.java

public class GameActivity extends AppCompatActivity {

   private static final String TAG = "GameActivity";
   public static final int SPAN_COUNT = 3;
   public static final int BLANK_BRICK = 8;
   public static final int[][] GOAL_STATUS = {{0, 1, 2}, {3, 4, 5}, {6, 7, BLANK_BRICK}};
   public static final int MAIL_GAME_STARTED = 100;
   public static final int MAIL_STEP_MOVED = 101;
   public static final int MAIL_GAME_WON = 102;
   public static final int REQUEST_CODE_CHOOSE_PICTURE = 100;

   private Bitmap mFullBitmap;
   private Bitmap[] mBitmapBricks = new Bitmap[SPAN_COUNT * SPAN_COUNT];
   private Timer mTimer;
   private long mStartTime;
   private int mStepCount;

   private TextView mTvTime;
   private TextView mTvStep;
   private Button mBtnChooseAndStart;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Window window = getWindow();
        window.requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        window.setEnterTransition(new Explode());
        window.setExitTransition(new Explode());
    }




    setContentView(R.layout.activity_game);

    Mailbox.getInstance().atHome(this);

    mTvTime = findViewById(R.id.tv_time);
    mTvStep = findViewById(R.id.tv_step);
    mBtnChooseAndStart = findViewById(R.id.btn_choose_and_start);
}




@Override
protected void onDestroy() {
    super.onDestroy();
    Mailbox.getInstance().leave(this);
}

@SuppressLint("RestrictedApi")
private void startActivityForNewPicture() {
    Intent intent = new Intent(this, ChooseActivity.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        startActivityForResult(
                intent, REQUEST_CODE_CHOOSE_PICTURE,
                ActivityOptionsCompat.makeSceneTransitionAnimation(
                        this,
                        findViewById(R.id.btn_change_picture),
                        getString(R.string.bottom_button_trans_name)).toBundle());
    } else {
        startActivityForResult(intent, REQUEST_CODE_CHOOSE_PICTURE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_CHOOSE_PICTURE) {
        if (resultCode == RESULT_OK) {
            handleChooseResult(data.getData());
        }
    }
}

private void handleChooseResult(Uri uri) {
    try {
        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));

        // Delete the cache file CropImage generated
        IOUtils.deleteFile(uri.getPath());

        // Scale the bitmap to a proper size, avoiding waste of memory
        View container = findViewById(R.id.fl_board_container);
        assert container != null;
        int paddingHorizontal = container.getPaddingLeft() + container.getPaddingRight();
        int paddingVertical = container.getPaddingTop() + container.getPaddingBottom();
        mFullBitmap = Bitmap.createScaledBitmap(
                bitmap,
                container.getWidth() - paddingHorizontal,
                container.getHeight() - paddingVertical,
                false);

        cutBitmapIntoPieces();
        mBitmapBricks[SPAN_COUNT * SPAN_COUNT - 1] = BitmapFactory.decodeResource(getResources(), R.drawable.blank_brick);

        startNewGame();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

private void cutBitmapIntoPieces() {
    int dividerWidth = (int) getResources().getDimension(R.dimen.brick_divider_width);
    int brickWidth = (mFullBitmap.getWidth() - dividerWidth * (SPAN_COUNT - 1)) / SPAN_COUNT;
    int brickHeight = (mFullBitmap.getHeight() - dividerWidth * (SPAN_COUNT - 1)) / SPAN_COUNT;
    for (int i = 0; i < SPAN_COUNT; i++) {
        for (int j = 0; j < SPAN_COUNT; j++) {
            mBitmapBricks[i * SPAN_COUNT + j] = Bitmap.createBitmap(
                    mFullBitmap,
                    j * (brickWidth + dividerWidth),
                    i * (brickHeight + dividerWidth),
                    brickWidth, brickHeight);
        }
    }
}

private void startNewGame() {
    mBtnChooseAndStart.setVisibility(View.GONE);
    getSupportFragmentManager()
            .beginTransaction()
            .replace(R.id.fl_board_container, GameFragment.newInstance(mBitmapBricks, GOAL_STATUS))
            .commit();
}

@OnMailReceived
public void onMailReceived(Mail mail) {
    if (mail.from == GameFragment.class) {
        switch ((int) mail.content) {
            case MAIL_GAME_STARTED:
                L.d(TAG, "Game started");
                onGameStarted();
                break;
            case MAIL_STEP_MOVED:
                L.d(TAG, "Moved");
                onStepMoved();
                break;
            case MAIL_GAME_WON:
                L.d(TAG, "Game won");
                onGameWon();
                break;
        }
    }
}

@SuppressLint("SetTextI18n")
private void onGameStarted() {
    mStepCount = 0;
    mTvStep.setText(String.valueOf(mStepCount));
    mTvTime.setText("00:00");

    mStartTime = System.currentTimeMillis();
    mTimer = new Timer();
    mTimer.schedule(new TimerTask() {
        @SuppressLint("SimpleDateFormat")
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    long nowTime = System.currentTimeMillis();
                    Date span = new Date(nowTime - mStartTime);
                    SimpleDateFormat format = new SimpleDateFormat("mm:ss");
                    mTvTime.setText(format.format(span));
                }
            });
        }
    }, 0, 1000);
}

private void onStepMoved() {
    mStepCount++;
    mTvStep.setText(String.valueOf(mStepCount));
}

private void onGameWon() {
    mTimer.cancel();
    mTimer.purge();
    App.getMainHandler().postDelayed(new Runnable() {
        @Override
        public void run() {
            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.fl_board_container, WinFragment.newInstance(mFullBitmap))
                    .commit();


            new AlertDialog.Builder(GameActivity.
                    this)
                    .setTitle(getString(R.string.result))
                    .setMessage(String.format(getString(R.string.win_prompt_format), mTvTime.getText().toString(), mTvStep.getText().toString()))
                    .setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            startNewGame();
                        }
                    })
                    .show();


            /*
            UIUtils.toast(
                    GameActivity.this,
                    String.format(getString(R.string.win_prompt_format), mTvTime.getText().toString(), mTvStep.getText().toString()),
                    true);

            */

        }
    }, 500);
}

public void changePicture(View view) {
    startActivityForNewPicture();
}

public void restart(View view) {
    if (mFullBitmap == null) {
        // Not started, so cannot restart
        UIUtils.toast(this, getString(R.string.not_started));
        return;
    }

    new AlertDialog.Builder(this)
            .setTitle(getString(R.string.restart))
            .setMessage(getString(R.string.confirm_restart_msg))
            .setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    startNewGame();
                }
            })
            .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            })
            .show();
}

public void lookUpOriginalPicture(View view) {
    if (mFullBitmap == null) {
        // Not started, so cannot restart
        UIUtils.toast(this, getString(R.string.not_started));
        return;
    }

    View alertView = View.inflate(this, R.layout.dialog_loop_up, null);
    ImageView imageView = alertView.findViewById(R.id.iv_image);
    imageView.setImageBitmap(mFullBitmap);
    final AlertDialog dialog = new AlertDialog.Builder(this)
            .setView(alertView)
            .create();
    alertView.setOnTouchListener(new View.OnTouchListener() {
        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            dialog.dismiss();
            return true;
        }
    });
    dialog.show();
}

public void chooseAndStart(View view) {
    startActivityForNewPicture();
}
}

ChooseActivity.java

public class ChooseActivity extends AppCompatActivity {
private static final int CHOOSER_SPAN_COUNT = 2;

private final int[] mResIds = new int[]{
        R.mipmap.pic_1, R.mipmap.pic_2, R.mipmap.pic_3,
        R.mipmap.pic_4, R.mipmap.pic_5, R.mipmap.pic_6,
        R.mipmap.pic_7, R.mipmap.pic_8
};

private Uri[] mUris = new Uri[mResIds.length];


private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE};

private static int REQUEST_PERMISSION_CODE = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_choose);

    for (int i = 0; i < mResIds.length; i++) {
        mUris[i] = ResUtils.getUriOfResource(this, mResIds[i]);
    }

    initView();
}

private void initView() {
    RecyclerView recyclerView = findViewById(R.id.rv_pics);
    assert recyclerView != null;
    CommonRecyclerViewAdapter<Uri> adapter = new CommonRecyclerViewAdapter<Uri>(this, mUris, R.layout.choose_pic_item) {
        @Override
        public void onItemViewAppear(ViewHolder holder, Uri uri, int position) {
            holder.setViewImageResource(R.id.iv_image, mResIds[position]);
        }
    };
    adapter.setOnItemClickListener(new CommonRecyclerViewAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(View view, int position) {
            returnUri(mUris[position]);
        }
    });
    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new GridLayoutManager(this, CHOOSER_SPAN_COUNT));
    recyclerView.addItemDecoration(new SquareGridSpacingItemDecoration(this, R.dimen.brick_divider_width));
}

public void chooseFromGallery(View view) {

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
        }
    }

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    startActivityForResult(intent, CropImage.PICK_IMAGE_CHOOSER_REQUEST_CODE);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_PERMISSION_CODE) {
        for (int i = 0; i < permissions.length; i++) {
            Log.i("MainActivity", "perm:" + permissions[i] + ",res:" + grantResults[i]);
        }
    }
}




@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case CropImage.PICK_IMAGE_CHOOSER_REQUEST_CODE: {
            if (resultCode == RESULT_OK) {
                CropImage.activity(Objects.requireNonNull(data.getData()))
                        .setActivityTitle(getString(R.string.crop))
                        .setAspectRatio(1, 1)
                        .setFixAspectRatio(true)
                        .start(this);
            }
            break;
        }
        case CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE: {
            if (resultCode == RESULT_OK) {
                CropImage.ActivityResult result = CropImage.getActivityResult(data);
                returnUri(result.getUri());
            }
            break;
        }
    }
}

private void returnUri(Uri uri) {
    Intent intent = new Intent();
    intent.setData(uri);
    setResult(RESULT_OK, intent);
    finish();
}
}

如何修改源代码?

1 个答案:

答案 0 :(得分:0)

当服务和应用程序之间交换大量数据时会发生这种情况(这涉及传输大量缩略图)。实际上,数据大小约为500kb,而IPC事务缓冲区大小设置为1024KB。我不确定为什么它超出了事务缓冲区。

当您通过意图附加传递大量数据时,也会发生这种情况。 因此,最终解决此 TransactionTooLarge 异常的方法是,确定具有下级片段,视图等将数据包添加到数据包中的Activity。然后在“活动”中运行此代码:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //Clear the Activity's bundle of the subsidiary fragments' bundles.
    outState.clear();
}

这为我解决了。希望这可以帮助某人!