通过Intent传输图片导致广播消息异常的问题根因分析(通过分析Android源码反向推理)(一)

2014-11-24 09:21:51 · 作者: · 浏览: 0
Music应用负责音乐的播放,如果某音乐还有图片,也需要把图片显示出来;
当Music应用播放的音乐发生切换后,需要通过广播消息,将正在播放的音乐的名称、图片等通过广播消息通知给B应用。
如果播放的是歌曲1,应用B可以正常收到歌曲1的名称、图片等;但如果切换到歌曲2,应用B无法收到广播消息。
Music应用中发送广播消息的代码如下:
[java]
System.out.println("play " + "send intent, musicTitle="
+ getTrackName() + " musicAlbum" + getAlbumName());
Intent intent = new Intent();
intent.setAction("com.zhao3546.ACTION_MUSIC_DETAIL");
intent.putExtra("musicTitle", getTrackName());
intent.putExtra("musicAlbum", getAlbumName());
Bitmap bmp = MusicUtils.getArtwork(this.getApplicationContext(),
getAudioId(),
getAlbumId());
intent.putExtra("musicImage", bmp);
System.out.println("bmp.getByteCount() = " + bmp.getByteCount());
sendBroadcast(intent);
B应用中动态注册接收广播消息的代码如下:
[java]
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.zhao3546.ACTION_MUSIC_DETAIL");
registerReceiver(mReceiver, intentFilter);
[java]
private class MusicDetailReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
final String title = intent.getStringExtra("musicTitle");
final String album = intent.getStringExtra("musicAlbum");
System.out.println("MusicDetailReceiver.onReceiver" + " title="
+ title + " album=" + album);
final Bitmap bmp = (Bitmap) intent.getParcelableExtra("musicImage");
播放歌曲1,输出的日志如下:
[plain]
09-11 16:12:16.732: I/System.out(14177): play send intent, musicTitle=最近超级火热的变形金刚简单机械短信息音效 musicAlbumwww.mozhao.net
09-11 16:12:16.776: I/System.out(14177): bmp.getByteCount() = 367236
09-11 16:12:16.802: I/System.out(13265): MusicDetailReceiver.onReceiver title=最近超级火热的变形金刚简单机械短信息音效 album=www.mozhao.net
播放歌曲2,输出的日志如下:
[java]
09-11 16:12:25.266: I/System.out(14177): play send intent, musicTitle=Bach-Goldberg Variations 1 2 3 musicAlbumClassical 1
09-11 16:12:25.329: I/System.out(14177): bmp.getByteCount() = 524288
在使用歌曲1测试时,和使用歌曲2测试时,中间我还修改过一些代码,一开始一起以为修改代码引入的问题;
但后来使用歌曲1测试发现最新的代码也是好使的,再仔细分析日志,发现在 bmp.getByteCount() = 524288 这行日志有一个错误日志,见红色字体:
09-11 16:12:25.266: I/System.out(14177): play send intent, musicTitle=Bach-Goldberg Variations 1 2 3 musicAlbumClassical 1
09-11 16:12:25.329: I/System.out(14177): bmp.getByteCount() = 524288
09-11 16:12:25.342: E/JavaBinder(9985): !!! FAILED BINDER TRANSACTION !!!
手头有Android 4.2.2完整的源码,根据“FAILED BINDER TRANSACTION” 搜索了一下代码,发现是在 android_util_Binder.cpp 这个类的signalExceptionForError中输出的:
[cpp]
void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
bool canThrowRemoteException)
{
switch (err) {
...
case FAILED_TRANSACTION:
ALOGE("!!! FAILED BINDER TRANSACTION !!!");
// TransactionTooLargeException is a checked exception, only throw from certain methods.
// FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
// but it is not the only one. The Binder driver can return BR_FAILED_REPLY
// for other reasons also, such as if the transaction is malformed or