Android Java Binder 失败的 BINDER 事务(TRANSACTION)?

20

我正在尝试从服务中下载图像并在活动中显示它,但我一直得到

 java binder FAILED BINDER TRANSACTION

这是我的服务代码

public class DownloadImageService extends Service {

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    new LoadImageAsync().execute(intent.getStringExtra("type"));
    return Service.START_NOT_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

private class LoadImageAsync extends AsyncTask<String, Void, String> {
    byte[] compressedImage;
    Bitmap bmp;
    String img;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params) {

        try {
            URL url = new URL(imgUrl);
            bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
            compressedImage = CompressBitmap.compresssImage(bmp);
            img = Base64.encodeToString(compressedImage, Base64.DEFAULT);

        } catch (IOException e) {
            compressedImage = null;
            bmp = null;
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if (compressedImage != null) {
            Intent i = new Intent(getApplicationContext(), OtherCampaignActivity.class);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            i.putExtra("image_byte", img);
            startActivity(i);
        }
        stopService(new Intent(getApplicationContext(), DownloadImageService.class));
    }
}

}

压缩函数

public static byte[] compresssImage(Bitmap b) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    b.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] compressedByteArray = stream.toByteArray();
    return compressedByteArray;
}

我的活动

public class OtherActivity extends AppCompatActivity {
private ImageView iv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_other);
    iv = (ImageView) findViewById(R.id.imageViewCam);
    byte[] byteArray =      Base64.decode(getIntent().getStringExtra("image_byte"), Base64.DEFAULT);
    //        byte[] byteArray = getIntent().getExtras().getByteArray("image_byte");
    Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
    iv.setImageBitmap(bitmap);

}

@Override
public void onBackPressed() {
    super.onBackPressed();
    finish();
}
}

代码存在什么问题。活动未能启动。

应用程序没有崩溃。我只在Logcat中看到了这个:

06-30 12:38:36.800 29992-29992/com.vt.enit E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!

我猜这可能是由于大位图引起的。


整个堆栈跟踪是什么? - pskink
应用程序没有崩溃。我只收到了这个:06-30 12:38:36.800 29992-29992 / com.vt.enit E / JavaBinder﹕!!!失败的绑定器事务!!! - WISHY
在调用 startActivity(i) 之前(在 i.putExtra("image_byte", img); 后面),请尝试使用 Log.d 记录 img 的大小。 - pskink
3051kb 是位图的大小。 - WISHY
让我们在聊天中继续这个讨论 - WISHY
显示剩余4条评论
2个回答

14

创建图像缓存解决了我的问题。

private LruCache<String, Bitmap> mMemoryCache;

@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an
// int in its constructor.
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;

mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
    @Override
    protected int sizeOf(String key, Bitmap bitmap) {
        // The cache size will be measured in kilobytes rather than
        // number of items.
        return bitmap.getByteCount() / 1024;
    }
};
...
}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
    mMemoryCache.put(key, bitmap);
}
 }

public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}

参考: 缓存位图


这里的String key是什么? - Sudhansu
Lrucache作为键值对工作。您可以提供任何键,例如“profile”,并仅使用此键访问位图。 - WISHY
很棒的解决方案,谢谢!将 LruCache 引用设置为静态是否会有任何问题? - Justin Case
@JustinCase 我认为将其设置为静态不会有任何问题。LruCache 将一直保持活动状态,直到应用程序的生命周期结束。 - WISHY

8

发送意图(extra)时,由于您试图发送的图像太大了,因此发送失败。使用IPC通信技术(如意图或服务/绑定器)无法发送图像,因为Android版本不同,限制为1MB / 10MB。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接