在非UI线程执行下班后刷新SimpleCursorAdapter [英] Refresh a SimpleCursorAdapter after performing work on a non-UI thread

查看:156
本文介绍了在非UI线程执行下班后刷新SimpleCursorAdapter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图调用.notifyDataSetChange()在SimpleCursorAdapter从XML解析非UI线程显示在ListView和不能为我的生活弄清楚如何。我找遍了所有我发现是讲从ListView控件本身,我没有做内刷新的文章。我不能想出一个办法来传递的适配器或从父或任何我需要做的,从另一个线程调用它的方法得到它。

ListView控件将更新罚款,下一次我启动活动,但我希望它尽快XML解析是这样做的用户会马上看到新数据刷新。

答案可能是简单的;它只是躲避我。在此先感谢您的帮助!

下面是我的code:

 公共类DirectoryListActivity扩展DirectoryActivity {

公众最终处理程序mHandler =新的处理程序();

@覆盖
公共无效的onCreate(包savedInstanceState){

    super.onCreate(savedInstanceState);
    的setContentView(R.layout.directory_list);

    //填充ListView
    SQLiteQueryBuilder QueryBuilder的=新SQLiteQueryBuilder();
    queryBuilder.setTables(
        directoryPeople.PEOPLE_TABLE
    );

    串asColumnsToReturn [] = {
            // SNIP
    };

    mCursor = queryBuilder.query(MDB,asColumnsToReturn,NULL,NULL,
            NULL,NULL,directoryPeople.DEFAULT_SORT_ORDER);

    startManagingCursor(mCursor);

//这里的适配器
    SimpleCursorAdapter适配器=新SimpleCursorAdapter(这一点,
            R.layout.directory_people_item,mCursor,
            新的String [] {
                // SNIP
            新的INT [] {
                // SNIP
    );

    ListView的AV =(ListView控件)findViewById(R.id.listPeople);
    av.setAdapter(适配器);

    //在后台执行同步
    startXMLParseThread();

}

    公共无效startXMLParseThread(){

    新的Thread(){

        布尔成功= FALSE;

        公共无效的run(){
            尝试 {
                // XML解析和表更新code

            }赶上(例外五){
                成功= FALSE;
            }

            mHandler.post(新的Runnable(){
                公共无效的run(){
                    TextView的txtUpdateStatus =(TextView中)findViewById(R.id.txtUpdateStatus);
                    如果(成功){
                        txtUpdateStatus.setText(R.string.synced);
                    } 其他 {
                        txtUpdateStatus.setText(R.string.sync_failed);
                    }
                    adapter.notifyDataSetChanged(); // ECLIPSE恨
                }
            });
        }
    }。开始();
    }
}
}
 

解决方案

没有必要建立一个新的适配器...

.notifyDataSetChanged()应该被称为只有在实际情况下更改(插入或删除的行)的数据行,如果你刚刚更新了值的行一个简单的调用到<一个href="http://developer.android.com/reference/android/database/Cursor.html#requery%28%29">requery()在游标应该足够:

  adapter.getCursor()重新查询();
 

编辑:按您的意见我看到你有其实是一个编译的问题...

您必须声明适配器作为一个类成员(前/后mHandler声明它:私人SimpleCursorAdapter适配器

然后,当你初始化,替换

  SimpleCursorAdapter适配器=新SimpleCursorAdapter(这一点,
    R.layout.directory_people_item,mCursor,
    新的String [] {
        // SNIP
        新的INT [] {
        // SNIP
);
 

 适配器=新SimpleCursorAdapter(这一点,
    R.layout.directory_people_item,mCursor,
    新的String [] {
        // SNIP
        新的INT [] {
        // SNIP
);
 

I'm trying to call .notifyDataSetChange() on a SimpleCursorAdapter displayed in a ListView from an XML-parsing non-UI thread and can't for the life of me figure out how. I've searched all over and all I've found are articles that talk about refreshing from within the ListView itself, which I'm not doing. I can't figure out a way to pass in the adapter or get it from the parent or whatever I need to do to call a method on it from another thread.

The ListView will update fine the next time I launch the activity, but I want it to refresh as soon as the XML parsing is done so that the user will see the new data immediately.

The answer's probably simple; it's just eluding me. Thanks in advance for any help!

Here's my code:

public class DirectoryListActivity extends DirectoryActivity {

public final Handler mHandler = new Handler();

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.directory_list);

    // Populate the ListView
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setTables(
        directoryPeople.PEOPLE_TABLE
    );

    String asColumnsToReturn[] = { 
            //snip
    };

    mCursor = queryBuilder.query(mDB, asColumnsToReturn, null, null,
            null, null, directoryPeople.DEFAULT_SORT_ORDER);

    startManagingCursor(mCursor);

// HERE'S THE ADAPTER
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            R.layout.directory_people_item, mCursor,
            new String[]{
                //snip
            new int[]{
                //snip
    ); 

    ListView av = (ListView)findViewById(R.id.listPeople);
    av.setAdapter(adapter);

    //Perform sync in background
    startXMLParseThread();

}

    public void startXMLParseThread() {

    new Thread () {

        boolean success = false;

        public void run() {
            try {
                // XML-Parsing and Table-Updating code

            } catch (Exception e) {
                success = false;
            }

            mHandler.post(new Runnable() {
                public void run() {
                    TextView txtUpdateStatus = (TextView)findViewById(R.id.txtUpdateStatus);
                    if (success) {
                        txtUpdateStatus.setText(R.string.synced);
                    } else {
                        txtUpdateStatus.setText(R.string.sync_failed);
                    }
                    adapter.notifyDataSetChanged(); // ECLIPSE HATES
                }
            });
        }
    }.start();
    }
}
}

解决方案

No need to create a new adapter...

.notifyDataSetChanged() should be called only in case the data rows actually changed (inserted or deleted rows), in case you just updated the values on rows a simple call to requery() on your cursor should be enough:

adapter.getCursor().requery();

Edit: by your comment I see that you have in fact a compilation problem...

You must declare the adapter as a class member (before/after mHandler declare it: private SimpleCursorAdapter adapter)

Then when you initialize it, replace

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
    R.layout.directory_people_item, mCursor,
    new String[]{
        //snip
        new int[]{
        //snip
); 

with:

adapter = new SimpleCursorAdapter(this,
    R.layout.directory_people_item, mCursor,
    new String[]{
        //snip
        new int[]{
        //snip
); 

这篇关于在非UI线程执行下班后刷新SimpleCursorAdapter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆