android 中无法使用 Loadermanager 将 BLOB 转换为字符串
Unable to convert BLOB to String using Loadermanager in android
我有一个具有以下结构的 table。
public static final String TABLE_NAME = "contact";
public static final String ID = "_id";
public static final String DEVICE_ID = "device_id";
public static final String NAME = "name";
public static final String CONTACT = "contact";
public static final String IMAGE = "image";
private static final int VERSION = 1;
private static final String CREATE_TABLE_QUERY = "CREATE TABLE "
+ TABLE_NAME + "( " + ID + " INTEGER PRIMARY KEY , " + DEVICE_ID
+ " TEXT NOT NULL , " + NAME + " TEXT NOT NULL , " + CONTACT
+ " TEXT NOT NULL ,"
+ IMAGE + " BLOB " +
" ) ";
我已经以 BLOB 形式存储联系人 table 中的图像。现在我必须从 table 检索 device_id,name , image 并将结果附加到 view .
我为此使用了 Loadermanager。
public class FriendList extends Activity implements OnItemClickListener,
LoaderManager.LoaderCallbacks {
ListView friendList;
SimpleCursorAdapter simpleCursorAdapter;
CursorLoader cursorLoader;
LoaderManager.LoaderCallbacks loaderCallback;
static final int CONTACT_LOADER_ID = 77;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.friend_list);
friendList = (ListView) findViewById(R.id.lvFriendList);
String[] uiBindFrom = new String[] { MyContacts.NAME,
MyContacts.DEVICE_ID ,MyContacts.IMAGE};
int[] idBindTo = { R.id.tvFriendName, R.id.tvDeviceID ,R.id.ivContactProfile};
loaderCallback = this;
simpleCursorAdapter = new SimpleCursorAdapter(FriendList.this,
R.layout.custom_friend_list, null, uiBindFrom, idBindTo, 0);
friendList.setAdapter(simpleCursorAdapter);
friendList.setOnItemClickListener(this);
getLoaderManager().initLoader(CONTACT_LOADER_ID, new Bundle(),
loaderCallback);
}
这里R.id.ivContactProfile是ImageView的id。
@Override
public Loader onCreateLoader(int id, Bundle args) {
String[] projectionFields = new String[] { MyContacts.ID,
MyContacts.NAME, MyContacts.DEVICE_ID,MyContacts.IMAGE };
cursorLoader = new CursorLoader(FriendList.this,
MyContacts.CONTENT_URI, projectionFields, null, null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader loader, Cursor cursor) {
switch (loader.getId()) {
case CONTACT_LOADER_ID:
simpleCursorAdapter.swapCursor(cursor);
break;
}
}
基本上我有图像以 byte[] 形式保存在 table 中,我必须将数据附加到视图,但它返回给我这样的异常。
05-21 19:30:05.169: E/AndroidRuntime(22609): android.database.sqlite.SQLiteException: unknown error: Unable to convert BLOB to string
这是完整的日志。
05-21 19:30:05.169: E/AndroidRuntime(22609): FATAL EXCEPTION: main
05-21 19:30:05.169: E/AndroidRuntime(22609): android.database.sqlite.SQLiteException: unknown error: Unable to convert BLOB to string
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.database.CursorWindow.nativeGetString(Native Method)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.database.CursorWindow.getString(CursorWindow.java:450)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.database.CursorWrapper.getString(CursorWrapper.java:114)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.support.v4.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:135)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:256)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.AbsListView.obtainView(AbsListView.java:2452)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.ListView.measureHeightOfChildren(ListView.java:1250)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.ListView.onMeasure(ListView.java:1161)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4712)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1385)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.measureVertical(LinearLayout.java:670)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4712)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.measureVertical(LinearLayout.java:822)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4712)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
05-21 19:30:05.169: E/AndroidRuntime(22609): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2242)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1240)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2628)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.os.Handler.dispatchMessage(Handler.java:99)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.os.Looper.loop(Looper.java:137)
05-21 19:30:05.169: E/AndroidRuntime(22609): at android.app.ActivityThread.main(ActivityThread.java:4517)
05-21 19:30:05.169: E/AndroidRuntime(22609): at java.lang.reflect.Method.invokeNative(Native Method)
05-21 19:30:05.169: E/AndroidRuntime(22609): at java.lang.reflect.Method.invoke(Method.java:511)
05-21 19:30:05.169: E/AndroidRuntime(22609): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
05-21 19:30:05.169: E/AndroidRuntime(22609): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
05-21 19:30:05.169: E/AndroidRuntime(22609): at dalvik.system.NativeStart.main(Native Method)
谁能告诉我为什么会出现这个异常,我该如何解决这个问题?
谢谢!
我找到了问题的解决方案。正如@pskink 在他上面的评论中所建议的,我使用了 ViewBinder
。我像这样创建了一个 ViewBinder。
public class MyViewBinder implements ViewBinder{
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
int viewID = view.getId();
switch(viewID){
case R.id.tvFriendName :
TextView friendName = (TextView) view;
String friend_name;
friend_name = cursor.getString(cursor.getColumnIndex(MyContacts.NAME));
friendName.setText(friend_name);
break;
case R.id.tvDeviceID :
TextView deviceID = (TextView) view;
String device_id = cursor.getString(cursor.getColumnIndex(MyContacts.DEVICE_ID));
deviceID.setText(device_id);
break;
case R.id.ivContactProfile :
ImageView contactProfile = (ImageView) view;
byte[] imageBytes = cursor.getBlob(cursor.getColumnIndex(MyContacts.IMAGE));
if(imageBytes != null ){
// Pic image from database
contactProfile.setImageBitmap(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length));
}else {
// If image not found in database , assign a default image
contactProfile.setBackgroundResource(R.drawable.bubble_a);
}
break;
}
return true;
}
}
然后我为我的 SimpleCursorAdapter 设置了 ViewBinder。
simpleCursorAdapter.setViewBinder( new MyViewBinder());
它对我很有效。这是输出。
我有一个具有以下结构的 table。
public static final String TABLE_NAME = "contact";
public static final String ID = "_id";
public static final String DEVICE_ID = "device_id";
public static final String NAME = "name";
public static final String CONTACT = "contact";
public static final String IMAGE = "image";
private static final int VERSION = 1;
private static final String CREATE_TABLE_QUERY = "CREATE TABLE "
+ TABLE_NAME + "( " + ID + " INTEGER PRIMARY KEY , " + DEVICE_ID
+ " TEXT NOT NULL , " + NAME + " TEXT NOT NULL , " + CONTACT
+ " TEXT NOT NULL ,"
+ IMAGE + " BLOB " +
" ) ";
我已经以 BLOB 形式存储联系人 table 中的图像。现在我必须从 table 检索 device_id,name , image 并将结果附加到 view .
我为此使用了 Loadermanager。
public class FriendList extends Activity implements OnItemClickListener, LoaderManager.LoaderCallbacks { ListView friendList; SimpleCursorAdapter simpleCursorAdapter; CursorLoader cursorLoader; LoaderManager.LoaderCallbacks loaderCallback; static final int CONTACT_LOADER_ID = 77; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.friend_list); friendList = (ListView) findViewById(R.id.lvFriendList); String[] uiBindFrom = new String[] { MyContacts.NAME, MyContacts.DEVICE_ID ,MyContacts.IMAGE}; int[] idBindTo = { R.id.tvFriendName, R.id.tvDeviceID ,R.id.ivContactProfile}; loaderCallback = this; simpleCursorAdapter = new SimpleCursorAdapter(FriendList.this, R.layout.custom_friend_list, null, uiBindFrom, idBindTo, 0); friendList.setAdapter(simpleCursorAdapter); friendList.setOnItemClickListener(this); getLoaderManager().initLoader(CONTACT_LOADER_ID, new Bundle(), loaderCallback); }
这里R.id.ivContactProfile是ImageView的id。
@Override public Loader onCreateLoader(int id, Bundle args) { String[] projectionFields = new String[] { MyContacts.ID, MyContacts.NAME, MyContacts.DEVICE_ID,MyContacts.IMAGE }; cursorLoader = new CursorLoader(FriendList.this, MyContacts.CONTENT_URI, projectionFields, null, null, null); return cursorLoader; } @Override public void onLoadFinished(Loader loader, Cursor cursor) { switch (loader.getId()) { case CONTACT_LOADER_ID: simpleCursorAdapter.swapCursor(cursor); break; } }
基本上我有图像以 byte[] 形式保存在 table 中,我必须将数据附加到视图,但它返回给我这样的异常。
05-21 19:30:05.169: E/AndroidRuntime(22609): android.database.sqlite.SQLiteException: unknown error: Unable to convert BLOB to string
这是完整的日志。
05-21 19:30:05.169: E/AndroidRuntime(22609): FATAL EXCEPTION: main 05-21 19:30:05.169: E/AndroidRuntime(22609): android.database.sqlite.SQLiteException: unknown error: Unable to convert BLOB to string 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.database.CursorWindow.nativeGetString(Native Method) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.database.CursorWindow.getString(CursorWindow.java:450) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.database.CursorWrapper.getString(CursorWrapper.java:114) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.support.v4.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:135) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:256) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.AbsListView.obtainView(AbsListView.java:2452) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.ListView.measureHeightOfChildren(ListView.java:1250) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.ListView.onMeasure(ListView.java:1161) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4712) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1385) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.measureVertical(LinearLayout.java:670) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4712) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.measureVertical(LinearLayout.java:822) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4712) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293) 05-21 19:30:05.169: E/AndroidRuntime(22609): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2242) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.View.measure(View.java:12865) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1240) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2628) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.os.Handler.dispatchMessage(Handler.java:99) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.os.Looper.loop(Looper.java:137) 05-21 19:30:05.169: E/AndroidRuntime(22609): at android.app.ActivityThread.main(ActivityThread.java:4517) 05-21 19:30:05.169: E/AndroidRuntime(22609): at java.lang.reflect.Method.invokeNative(Native Method) 05-21 19:30:05.169: E/AndroidRuntime(22609): at java.lang.reflect.Method.invoke(Method.java:511) 05-21 19:30:05.169: E/AndroidRuntime(22609): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993) 05-21 19:30:05.169: E/AndroidRuntime(22609): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760) 05-21 19:30:05.169: E/AndroidRuntime(22609): at dalvik.system.NativeStart.main(Native Method)
谁能告诉我为什么会出现这个异常,我该如何解决这个问题?
谢谢!
我找到了问题的解决方案。正如@pskink 在他上面的评论中所建议的,我使用了 ViewBinder
。我像这样创建了一个 ViewBinder。
public class MyViewBinder implements ViewBinder{
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
int viewID = view.getId();
switch(viewID){
case R.id.tvFriendName :
TextView friendName = (TextView) view;
String friend_name;
friend_name = cursor.getString(cursor.getColumnIndex(MyContacts.NAME));
friendName.setText(friend_name);
break;
case R.id.tvDeviceID :
TextView deviceID = (TextView) view;
String device_id = cursor.getString(cursor.getColumnIndex(MyContacts.DEVICE_ID));
deviceID.setText(device_id);
break;
case R.id.ivContactProfile :
ImageView contactProfile = (ImageView) view;
byte[] imageBytes = cursor.getBlob(cursor.getColumnIndex(MyContacts.IMAGE));
if(imageBytes != null ){
// Pic image from database
contactProfile.setImageBitmap(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length));
}else {
// If image not found in database , assign a default image
contactProfile.setBackgroundResource(R.drawable.bubble_a);
}
break;
}
return true;
}
}
然后我为我的 SimpleCursorAdapter 设置了 ViewBinder。
simpleCursorAdapter.setViewBinder( new MyViewBinder());
它对我很有效。这是输出。