如何在SyncAdapter完成同步后刷新Android ListView

3
我已经扩展了一个AbstractThreadedSyncAdapter,并通过代码每x分钟或手动请求同步来自动同步与我的服务器的数据。它完美地工作。
现在下一步是自动更新包含消息和另一个包含指定作业的ListView。
我找到的示例都假定您从同一Activity中更改数据集,或者您以其他方式访问ListView绑定到的数据库游标。不幸的是对于Android Sync Adapter而言,情况并非如此。它在后台运行,没有任何有用的参考资料,据我所知。
我的SyncAdapter:
public class VttSyncAdapter extends AbstractThreadedSyncAdapter {
    private final AccountManager mAccountManager;

    public VttSyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
        mAccountManager = AccountManager.get(context);
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
        Log.d("Vtt", "onPerformSync for account[" + account.name + "]");
        try 
        {         
            //GET SOME DATA FROM WEBSERVICE AND INSERT INTO SQLITE DB
        } catch (IOException e) {
            e.printStackTrace();
        }

        //WHAT WOULD ONE DO HERE TO ALERT THE LISTVIEW THAT IT SHOULD REFRESH?

        } catch (Exception e) {
            e.printStackTrace();

    }

    public String getsharedresourcestring(String key)
    {
        Context context = getContext();
        SharedPreferences sharedPref = context.getSharedPreferences(context.getString(R.string.preference_file_key), MODE_PRIVATE);
        return sharedPref.getString(key,null);
    }

}

我日程表的片段代码:

public class ScheduleFragment extends Fragment {
    private ListView listView;
    private List<DeliveryScheduleEntryModel> schedules;


    public ScheduleFragment() {
        // Required empty public constructor
    }

    public static ScheduleFragment newInstance(String param1, String param2) {
        ScheduleFragment fragment = new ScheduleFragment();
        Bundle args = new Bundle();
        //args.putString(ARG_PARAM1, param1);
        //args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            //mParam1 = getArguments().getString(ARG_PARAM1);
            //mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View ret = inflater.inflate(R.layout.fragment_schedule, container, false);

        listView = (ListView) ret.findViewById(R.id.listViewSchedule);

        //GET OUR DATA
        Activity activity = this.getActivity();
        ContentResolver contentResolver = activity.getContentResolver();
        schedules = getSchedule(contentResolver);

        DeliveryScheduleEntryModelList customList = new DeliveryScheduleEntryModelList(activity, schedules);

        listView.setAdapter(customList);
        return ret;
    }

    public List<DeliveryScheduleEntryModel> getSchedule(ContentResolver cr)
    {
        Context context = getContext();
        VttDataSource db = new VttDataSource(context);
        db.open();
        List<DeliveryScheduleEntryModel> ret = db.getAllDeliveryScheduleEntryModel();
        db.close();

        return ret;
    }
}
1个回答

3

//如何提醒ListView应该刷新?

可以像下面这样发送一个本地广播:

Intent intent = new Intent();
intent.setAction("com.your_package.name.REFRESH_LIST");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

让带有 ListViewFragment 声明一个 BroadcastReceiver

private BroadcastReceiver myReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {

        String sAction = intent.getAction();
        if ("com.your_package.name.REFRESH_LIST".equals(sAction) )
        {
            // update the ListView here
        }
    }
}

onAttach()中注册广播接收器 BroadcastReceiver

IntentFilter myFilter = new IntentFilter();
myFilter.addAction("com.your_package.name.REFRESH_LIST");
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, myFilter);

不要忘记在onDetach()中取消注册。

LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);

这样,只要FragmentActivity连接,Fragment将会接收到更新消息。

另一种选择是使用某种类型的事件总线(如greenrobot、Otto等)。


听起来你知道你在说什么 ;) 谢谢。 - Captain Kenpachi
@Captain Kenpachi - 感谢您的信任,我希望我们能解决这个问题 ;) 我认为您的VttSyncAdapter正在后台运行,因此它是Service的一部分(该Service没有UI),而相关的Fragment在前台(因此它将接收Broadcast)。也许您可以发布更多的代码,以便我更好地理解您的情况? - Bö macht Blau
我遵循了Android创建同步适配器服务的最佳实践。 - Captain Kenpachi
1
好的。最终我选择了你提出的使用EventBus的建议。所以谢谢你。我不得不将SyncAdapter移动到与应用程序相同的线程中,以便在我想要它们注册的位置获取事件。我最初在EventBus上遇到了同样的问题,但从清单中删除“android:process =”:sync“就解决了问题。即使应用程序停止,同步仍然会运行,所以一切都很好。 - Captain Kenpachi
这个不起作用 - Lalit Jadav
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接