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

SyncAdapter完成同步后如何刷新Android ListView,android,listview,synchronization,Android,Listview,Synchronization,我扩展了AbstractThreadedSyncAdapter,让它每隔x分钟或当我通过代码手动请求同步时自动与我的服务器同步数据。它工作得很好 因此,现在下一步是自动更新包含消息的ListView和另一个包含已分配作业的ListView 我找到的示例都假设您正在从同一活动中更改数据集,或者您可以访问ListView绑定到的数据库游标。不幸的是,对于Android同步适配器,情况并非如此。它在后台运行,据我所知,没有任何有用的参考 我的同步适配器: public class VttSyncAda

我扩展了AbstractThreadedSyncAdapter,让它每隔x分钟或当我通过代码手动请求同步时自动与我的服务器同步数据。它工作得很好

因此,现在下一步是自动更新包含消息的ListView和另一个包含已分配作业的ListView

我找到的示例都假设您正在从同一活动中更改数据集,或者您可以访问ListView绑定到的数据库游标。不幸的是,对于Android同步适配器,情况并非如此。它在后台运行,据我所知,没有任何有用的参考

我的同步适配器:

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;
    }
}
公共类ScheduleFragment扩展了片段{
私有列表视图列表视图;
私人名单附表;
公共ScheduleFragment(){
//必需的空公共构造函数
}
公共静态ScheduleFragment newInstance(字符串param1,字符串param2){
ScheduleFragment=新ScheduleFragment();
Bundle args=新Bundle();
//args.putString(ARG_PARAM1,PARAM1);
//args.putString(ARG_PARAM2,PARAM2);
fragment.setArguments(args);
返回片段;
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
如果(getArguments()!=null){
//mParam1=getArguments().getString(ARG_PARAM1);
//mParam2=getArguments().getString(ARG_PARAM2);
}
}
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
//为该碎片膨胀布局
视图ret=充气机。充气(R.layout.fragment\u明细表,容器,错误);
listView=(listView)ret.findViewById(R.id.listViewSchedule);
//获取我们的数据
Activity=this.getActivity();
ContentResolver ContentResolver=activity.getContentResolver();
schedules=getSchedule(contentResolver);
DeliveryScheduleEntryModelList customList=新的DeliveryScheduleEntryModelList(活动、计划);
setAdapter(自定义列表);
返回ret;
}
公共列表getSchedule(ContentResolver cr)
{
Context=getContext();
VttDataSource db=新VttDataSource(上下文);
db.open();
List ret=db.getAllDeliveryScheduleEntryModel();
db.close();
返回ret;
}
}
//在这里,我们将如何提醒LISTVIEW它应该刷新

发送本地广播,如下所示:

Intent intent = new Intent();
intent.setAction("com.your_package.name.REFRESH_LIST");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
片段
列表视图
声明一个
广播接收器

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()
中:

并且不要忘记取消注册,例如在
onDetach()

这样,只要
片段附加到
活动
,它就会获得更新消息


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

听起来你知道你在说什么;)谢谢。我在哪里申报收音机?它是一个内部类吗?我要在OnResume()中声明吗?我无法让它工作。当我从同一活动中广播时,我可以启动onReceive,但如果我将广播移动到后台同步活动,则相关片段不会接收广播。@Kenpachi上尉-感谢您的信任,我希望我们能解决此问题;)我认为您的VttSyncAdapter是在后台运行的,因此它是服务(没有UI)的一部分/由服务触发,而相关片段位于前台(因此它将获得广播)。也许你可以发布更多的代码,这样我就可以更好地理解你的场景了。最后,我同意你关于使用EventBus的其他建议。所以谢谢你。我必须将SyncAdapter移动到与应用程序相同的线程,才能将事件注册到我想要的位置。我最初在EventBus上也有同样的问题,但是从清单中删除“android:process=“:sync”就成功了。即使应用程序停止,同步仍然会运行,所以一切都很好。
IntentFilter myFilter = new IntentFilter();
myFilter.addAction("com.your_package.name.REFRESH_LIST");
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, myFilter);
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);