您的位置:首页 > 移动开发 > Android开发

android中Thread对于Adapter出现的报错情况的处理以及如何正确使用Spinner与SimpleCurosorAdapter

2015-07-16 15:55 666 查看
在开始之前,先说说这个博文的意思,因为之前有个小项目用到的是spinner与本地数据库 的数据 的连接,然后spinner会在Actiivity出现后马上调用数据库的数据,也就是在onCreate中实现这个功能。然后对于这块也确实出现了一些意想不到的错误,导致引导错了方向,所以Logcat出现的问题也是比较难以理解的。现在开始讲解代码。

先展示先前写的代码和报错的原因:

package com.example.hello;

import android.database.Cursor;

import android.os.Bundle;

import android.os.Handler;

import android.provider.Contacts.People;

import android.support.v4.widget.SimpleCursorAdapter;

import android.support.v7.app.ActionBarActivity;

import android.view.Menu;

import android.view.MenuItem;

import android.widget.Spinner;

import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

public Spinner listView;

SimpleCursorAdapter listAdapter = null;

Cursor cursor = null;

Handler handler = new Handler()

{

public void handleMessage(android.os.Message msg)

{

if(msg.what == 0x123)

{

if(listAdapter !=null)

{

listView.setAdapter(listAdapter);

}

else

{

Toast.makeText(MainActivity.this, "listAdapter为空", Toast.LENGTH_LONG).show();

}

}

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

listView = (Spinner)findViewById(R.id.list);

new Thread()

{

public void run()

{

cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);

startManagingCursor(cursor);

listAdapter= new SimpleCursorAdapter(MainActivity.this, android.R.layout.simple_expandable_list_item_1, cursor, new String[]{People.NAME}, new int[]{android.R.id.text1});

handler.sendEmptyMessage(0x123);

};

}.start();

}

}

后面需要在注册表里添加权限:<uses-permission

android:name="android.permission.READ_CONTACTS"

/>

这是一个Activity,然后Spinner在Layout里,我也是简单的设置一下,没有太多的花俏,在这段代码里我要实现的功能就是在新线程里调用数据库生成Cursor,然后接着在线程的run()里生成SimpleCursorAdapter,就是代码里的listAdapter。然后接下去就是给handler发送消息,通知更改界面,思路是这样子的,然后就出现错误:



07-16 07:34:13.356: E/AndroidRuntime(3954): FATAL EXCEPTION: Thread-119

07-16 07:34:13.356: E/AndroidRuntime(3954): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

07-16 07:34:13.356: E/AndroidRuntime(3954): at android.os.Handler.<init>(Handler.java:121)

07-16 07:34:13.356: E/AndroidRuntime(3954): at android.support.v4.widget.CursorAdapter$ChangeObserver.<init>(CursorAdapter.java:455)

07-16 07:34:13.356: E/AndroidRuntime(3954): at android.support.v4.widget.CursorAdapter.init(CursorAdapter.java:176)

07-16 07:34:13.356: E/AndroidRuntime(3954): at android.support.v4.widget.CursorAdapter.<init>(CursorAdapter.java:122)

07-16 07:34:13.356: E/AndroidRuntime(3954): at android.support.v4.widget.ResourceCursorAdapter.<init>(ResourceCursorAdapter.java:54)

07-16 07:34:13.356: E/AndroidRuntime(3954): at android.support.v4.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:63)

07-16 07:34:13.356: E/AndroidRuntime(3954): at com.example.hello.MainActivity$2.run(MainActivity.java:43)

07-16 07:34:13.432: D/libEGL(3954): loaded /system/lib/egl/libEGL_genymotion.so

07-16 07:34:13.432: D/(3954): HostConnection::get() New Host Connection established 0xb7e4be08, tid 3954

然后经过有一次意外的思路,终于把问题给解决了:给出代码:

package com.example.hello;

import android.database.Cursor;

import android.os.Bundle;

import android.os.Handler;

import android.provider.Contacts.People;

import android.support.v4.widget.SimpleCursorAdapter;

import android.support.v7.app.ActionBarActivity;

import android.view.Menu;

import android.view.MenuItem;

import android.widget.Spinner;

import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

public Spinner listView;

SimpleCursorAdapter listAdapter = null;

Cursor cursor = null;

Handler handler = new Handler()

{

public void handleMessage(android.os.Message msg)

{

if(msg.what == 0x123)

{

listAdapter= new SimpleCursorAdapter(MainActivity.this, android.R.layout.simple_expandable_list_item_1, cursor, new String[]{People.NAME}, new int[]{android.R.id.text1});

if(listAdapter !=null)

{

listView.setAdapter(listAdapter);

}

else

{

Toast.makeText(MainActivity.this, "listAdapter为空", Toast.LENGTH_LONG).show();

}

}

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

listView = (Spinner)findViewById(R.id.list);

new Thread()

{

public void run()

{

cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);

startManagingCursor(cursor);

handler.sendEmptyMessage(0x123);

};

}.start();

}

}

上面的代码终于实现了想要的功能,在这里补充一下,在安卓很久以前的版本,应该是2点的安卓版本的时候,安卓是允许在主线程里实现耗时操作的,可是因为这个会影响客户的体验,所以后面就改成在新线程thread里进行耗时操作,不允许在新线程进行ui更新,然后在handler里进行ui更新。所以上面错误的问题bug就是这个方面的原因,SimpleSursorAdapter是一个界面,所以不应该在新线程里实现SimpleCursorAdapter,所以导致了上面总总看不懂原因的错误在。

最后在这里,想搞笑一下,终于把问题解决了,好开心,屌丝程序员慢慢地要走上正轨了,加油!!!!!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: