You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二级Activity向主Activity传递VideoView帧Bitmap为空求助

Fixing Null Bitmap When Passing From Secondary Activity to Main Activity

Hey there, let's get to the bottom of why your Bitmap is showing up as null in the MainActivity even though it exists in your secondary Activity!

Why This Is Happening

Even though Bitmap implements the Parcelable interface, passing large Bitmaps directly via Intent.putExtra() often fails silently. The issue is the Binder transaction limit (typically around 1MB)—if your captured frame from the VideoView exceeds this size, the system drops the data, leaving you with a null value in the MainActivity. That’s why you can see the Bitmap in the secondary Activity but not in the main one.

Solutions to Try

1. Use a Static Variable (Quick Fix, Watch for Memory Leaks)

You can store the Bitmap in a static field in your MainActivity so the secondary Activity can set it directly before navigating back.

In MainActivity:

public static Bitmap capturedBitmap; // Static field to hold the image

In your secondary Activity:

videoField.setDrawingCacheEnabled(true);
videoField.buildDrawingCache();
Bitmap bm = videoField.getDrawingCache();

// Assign to the static variable instead of putting it in Intent
MainActivity.capturedBitmap = bm;

Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);

In MainActivity's onCreate():

if (capturedBitmap != null) {
    yourImageView.setImageBitmap(capturedBitmap);
    // Clear the static variable after use to avoid memory leaks
    capturedBitmap = null;
}

Note: Static variables can cause memory leaks if your Activity is destroyed and recreated (like on screen rotation). Use this only for simple, short-lived flows.

2. Save Bitmap to File and Pass the Path (Recommended for Most Cases)

Storing the Bitmap as a file and passing its path via Intent avoids Binder limits and is more reliable.

In your secondary Activity:

videoField.setDrawingCacheEnabled(true);
videoField.buildDrawingCache();
Bitmap bm = videoField.getDrawingCache();

// Save Bitmap to internal storage
String fileName = "captured_frame.png";
FileOutputStream fos = null;
try {
    fos = openFileOutput(fileName, Context.MODE_PRIVATE);
    bm.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (fos != null) {
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// Pass the file path via Intent
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("bitmap_path", fileName);
startActivity(intent);

In MainActivity's onCreate():

Intent intent = getIntent();
String bitmapPath = intent.getStringExtra("bitmap_path");
if (bitmapPath != null) {
    // Read Bitmap from file
    File file = new File(getFilesDir(), bitmapPath);
    Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
    yourImageView.setImageBitmap(bitmap);
    
    // Optional: Delete the file after use to save space
    file.delete();
}

3. Use a Custom Application Class (Alternative to Static Variables)

Store the Bitmap in your app's Application instance, which persists across all activities.

First, create a custom Application class:

public class MyApp extends Application {
    private Bitmap capturedBitmap;

    public Bitmap getCapturedBitmap() {
        return capturedBitmap;
    }

    public void setCapturedBitmap(Bitmap bitmap) {
        this.capturedBitmap = bitmap;
    }
}

Update your AndroidManifest.xml to use this class:

<application
    android:name=".MyApp"
    ...>
    <!-- Your activities here -->
</application>

In your secondary Activity:

videoField.setDrawingCacheEnabled(true);
videoField.buildDrawingCache();
Bitmap bm = videoField.getDrawingCache();

// Set the Bitmap in the Application instance
MyApp app = (MyApp) getApplicationContext();
app.setCapturedBitmap(bm);

Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);

In MainActivity's onCreate():

MyApp app = (MyApp) getApplicationContext();
Bitmap bitmap = app.getCapturedBitmap();
if (bitmap != null) {
    yourImageView.setImageBitmap(bitmap);
    // Clear the Bitmap after use
    app.setCapturedBitmap(null);
}

Final Tips

  • If you must use the Intent method for small images, compress the Bitmap first with bm.compress() to stay under the Binder limit.
  • Always clean up Bitmaps after use (call recycle() if needed) to avoid memory issues.

内容的提问来源于stack exchange,提问作者Mirko Marasco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:42:45