其他分享
首页 > 其他分享> > android – 在同步服务运行后刷新FragmentActivity中的片段

android – 在同步服务运行后刷新FragmentActivity中的片段

作者:互联网

在SyncAdapter的同步服务运行后,是否有任何优雅的解决方案可以在FragmentActivity的ViewPager中刷新片段中的视图?

我尝试在我的适配器上调用notifyDataSetChanged()和notifyDataSetInvalidated(),以及在我的视图(GridViews)上调用refreshDrawableState(),但无济于事.也许我一直在从错误的地方调用它们 – 我已经尝试在setUserVisibleHint中执行它,其中isVisible = true,希望在片段进入视图时触发它,但它不起作用.

我也一直在使用ASync调用SQLite数据库来满足我的数据需求,而不是内容提供程序,我认为这会使这更容易.没有内容提供商,我可以想到几种方法,但两者都不是很好.

有任何想法吗?如果愿意,我可以提供代码.谢谢.

解决方法:

我假设您只是为了解释而使用AsyncTask来加载光标,但是如果您使用的是Loader,ThreadPool或其他什么,它将会起作用.

从服务中,一旦新数据发生变化,我就会发送一个LocalBroadcast.活动可能存在与否,因此广播是让它知道新数据的好方法.所以从服务中你会做到:

    // that's an example, let's say your SyncAdapter updated the album with this ID
    // but you could create a simply "mybroadcast", up to you.
    Intent i = new Intent("albumId_" + albumId);
    LocalBroadcastManager.getInstance(this).sendBroadcast(i);

然后从具有Cursor的activity / fragment中,你将听到这样的广播:

    public void onResume(){
        // the filter matches the broadcast
        IntentFilter filter = new IntentFilter("albumId_" + albumId); 
        LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, filter);
    }
    public void onPause(){
        LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
    }

    // and of course you have to create a BroadcastReceiver
    private BroadcastReceiver myReceiver = new BroadcastReceiver(){
       @Override
       public void onReceive(Context context, Intent intent){
           // here you know that your data have changed, so it's time to reload it
           reloadData = new ReloadData().execute(); // you should cancel this task onPause()
       }
    };

正如我所说,下一部分取决于你用来加载光标的线程方法,这个例子我将在AsyncTask中显示,因为它非常受欢迎(但我真的相信你和世界上的每个开发人员都应该使用装载机模式).

private class ReloadData extends AsyncTask<Void, Void, Cursor> {
 protected Cursor doInBackground(Void... void) {
     // here you query your data base and return the new cursor
     ... query ...
     return cursor;
 }

 protected void onPostExecute(Cursor result) {
     // you said you're using a subclass of CursorAdater
     // so you have the method changeCursor, that changes the cursor and closes the old one
     myAdapter.changeCursor(result);
 }

}

我之前测试和使用的上述方法,我知道它的工作原理.有一种方法可以使用标志FLAG_REGISTER_CONTENT_OBSERVER并覆盖onContentChanged()来重新执行查询并交换光标,但我从未测试过它.它将是这样的:

使用构造函数CursorAdapter(Context context,Cursor c,int flags)初始化您的适配器,传递标志FLAG_REGISTER_CONTENT_OBSERVER并覆盖onContentChanged().在onContentChanged中,您将像上面一样执行AsyncTask.这样您就不必使用LocalBroadcastManager,因为数据库将发出警报.这种方法不是我的主要答案,因为我从未测试过它.

请注意,autoRequery已被弃用,因为它在UI线程中执行数据加载而不鼓励使用.

编辑:

我只是注意到内容观察者是API 11的事情.您有两种选择:1使用支持库:https://developer.android.com/reference/android/support/v4/widget/CursorAdapter.html或广播选项.

标签:android-syncadapter,android,android-fragments,android-viewpager,android-fragment
来源: https://codeday.me/bug/20190831/1776949.html