Can't create handler inside thread that has not called Looper.prepare()

1. 收到新信息时,出现运行时异常。

07-16 10:58:55.173: E/JavaBinder(31934): *** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
07-16 10:58:55.173: E/JavaBinder(31934): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
07-16 10:58:55.173: E/JavaBinder(31934):     at android.os.Handler.<init>(Handler.java:121)
07-16 10:58:55.173: E/JavaBinder(31934):     at android.widget.Toast$TN.<init>(Toast.java:364)
07-16 10:58:55.173: E/JavaBinder(31934):     at android.widget.Toast.<init>(Toast.java:98)
07-16 10:58:55.173: E/JavaBinder(31934):     at android.widget.Toast.makeText(Toast.java:252)
07-16 10:58:55.173: E/JavaBinder(31934):     at com.txrj.sms.activity.MessageListActivity$2.onChange(MessageListActivity.java:86)
07-16 10:58:55.173: E/JavaBinder(31934):     at android.database.ContentObserver.dispatchChange(ContentObserver.java:133)
07-16 10:58:55.173: E/JavaBinder(31934):     at android.database.ContentObserver$Transport.onChange(ContentObserver.java:65)
07-16 10:58:55.173: E/JavaBinder(31934):     at android.database.IContentObserver$Stub.onTransact(IContentObserver.java:53)
07-16 10:58:55.173: E/JavaBinder(31934):     at android.os.Binder.execTransact(Binder.java:338)
07-16 10:58:55.173: E/JavaBinder(31934):     at dalvik.system.NativeStart.run(Native Method)

2. 确定产生异常的代码,即如下的蓝色字体的语句。

private ContentObserver mInboxObserver = new ContentObserver(null) {
    public void onChange(boolean selfChange) {
        //Log.i("txrjsms", "receive a message.");           
        Cursor cursor = getContentResolver().query(Sms.Inbox.CONTENT_URI,
                new String[]{Sms._ID, Sms.THREAD_ID, Sms.TYPE, Sms.BODY, Sms.DATE, Sms.READ},
                "read = 0 and thread_id = " + mThreadId,
                null, null);
        TxrjMessage msg = null;
        if(cursor != null) {
            if (cursor.moveToFirst()) {
                Toast.makeText(mContext, "receive a message.", Toast.LENGTH_SHORT).show();
                msg = new TxrjMessage();
                msg.setMessageId(cursor.getInt(cursor.getColumnIndex(Sms._ID)));
                msg.setThreadId(cursor.getInt(cursor.getColumnIndex(Sms.THREAD_ID)));
                msg.setType(cursor.getInt(cursor.getColumnIndex(Sms.TYPE)));
                msg.setBody(cursor.getString(cursor.getColumnIndex(Sms.BODY)));
                msg.setTime(cursor.getLong(cursor.getColumnIndex(Sms.DATE)));
                cursor.close();
                ContentValues values = new ContentValues();
                values.put(Sms.READ, 1);
                getContentResolver().update(Sms.Inbox.CONTENT_URI, values,
                        "_id=" + msg.getMessageId(), null);
                mMessages.add(msg);
                mHandler.sendEmptyMessage(TxrjConstant.WHAT_NOTIFY_DATA_CHANGED);
            }
        }
    }
};

3. 异常原因分析。在ContentObserver的onChange方法中,调用了Toast.makeText方法。onChange方法应该在子线程运行,在android中的子线程中不能直接控制UI组件。

如果要调用Toast.makeText,可以通过mHandler.sendMessage来实现。

4. 错误信息中出现了Looper.prepare(),它又是如何使用的呢。

Can't create handler inside thread that has not called Looper.prepare()

posted on 2013-07-16 11:11  勤修  阅读(6854)  评论(0编辑  收藏  举报

导航