装载机不加载数据sqlite的数据发生变化时, [英] Loader not loading data when sqlite data changes

查看:325
本文介绍了装载机不加载数据sqlite的数据发生变化时,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 DialogFragment 是我的工作,以显示两个微调,肩并肩,一是显示驱动程序列表,其他车辆的清单。

来填充这些微调的数据是从SQLite数据库检索。我试图用一个 LoaderManager 来保持更新纺纱或同步的数据库表,(司机和车辆)。

当我添加/删除/编辑记录在任一数据库中的驱动程序表或车辆表格中,纺纱没有更新,驾驶员或车辆保持在离心器不变。

我不知道我失踪,因为我认为 LoaderManager 应该保持更新的列表或与右自动数据库表同步?

我创建了一个名为按钮 addDriverVehicle()这是应该允许用户添加另一个驱动器/汽车在未来,但现在我使用它作为一个测试删除驱动程序类型的模拟数据库表的变化,这样我可以看到,如果微调被自动更新,但它没有发生。该记录被删除,但微调将继续证明这一点。

 公共类DriverVehiclePickersDialogFragment扩展DialogFragment实现LoaderManager.LoaderCallbacks<游标>中OnItemSelectedListener {    公共静态最后弦乐ARG_LISTENER_TYPE =listenerType;
    公共静态最后弦乐ARG_DIALOG_TYPE =的DialogType;
    公共静态最后弦乐ARG_TITLE_RESOURCE =titleResource;
    公共静态最后弦乐ARG_SET_DRIVER =setDriver;
    公共静态最后弦乐ARG_SET_VEHICLE =setVehicle;    私有静态最终诠释DRIVERS_LOADER = 0;
    私有静态最终诠释VEHICLES_LOADER = 1;    私人DriverVehicleDialogListener mListener;    //这是所用的适配器来显示驾​​驶者和车辆的数据。
    SimpleCursorAdapter mDriversAdapter,mVehiclesAdapter;    //定义对话框视图
    私人查看MView的;    //商店驾驶员和车辆选择
    私人长期[] mDrivers,mVehicles;    //纱厂含驾驶员和车辆清单
    私人微调driversSpinner;
    私人微调vehiclesSpinner;    私有静态枚举ListenerType {
        活动中,片段
    }    公共静态枚举{的DialogType
        DRIVER_SPINNER,VEHICLE_SPINNER,DRIVER_VEHICLE_SPINNER
    }    公共接口DriverVehicleDialogListener {
        公共无效onDialogPositiveClick(长[] mDrivers,长[] mVehicles);
    }    公共DriverVehiclePickersDialogFragment(){
        //空的构造
        Log.d(默认,默认构造函数跑);
    }    公共静态的newInstance DriverVehiclePickersDialogFragment(DriverVehicleDialogListener监听器,捆绑dialogSettings){
        最后DriverVehiclePickersDialogFragment实例;        如果(听众的instanceof活动){
            例如=的createInstance(ListenerType.ACTIVITY,dialogSettings);
        }否则如果(听众的instanceof片段){
            例如=的createInstance(ListenerType.FRAGMENT,dialogSettings);
            instance.setTargetFragment((片段)监听器,0);
        }其他{
            抛出新抛出:IllegalArgumentException(listener.getClass()+必须是一个活动或片段);
        }        返回实例;
    }    私有静态DriverVehiclePickersDialogFragment的createInstance(ListenerType listenerType,捆绑dialogSettings){
        DriverVehiclePickersDialogFragment片段=新DriverVehiclePickersDialogFragment();        如果(!dialogSettings.containsKey(ARG_LISTENER_TYPE)){
            dialogSettings.putSerializable(ARG_LISTENER_TYPE,listenerType);
        }        如果(!dialogSettings.containsKey(ARG_DIALOG_TYPE)){
            dialogSettings.putSerializable(ARG_DIALOG_TYPE,DialogType.DRIVER_VEHICLE_SPINNER);
        }        如果(!dialogSettings.containsKey(ARG_TITLE_RESOURCE)){
            dialogSettings.putInt(ARG_TITLE_RESOURCE,0);
        }        fragment.setArguments(dialogSettings);
        返回片段;
    }    @覆盖
    公共无效onAttach(活动活动){
        super.onAttach(活动);        //了解如何获得DialogListener实例的回调事件发送到
        捆绑ARGS = getArguments();
        ListenerType listenerType =(ListenerType)args.getSerializable(ARG_LISTENER_TYPE);        开关(listenerType){
        活动情况:{
            //发送回调事件到托管活动
            mListener =(DriverVehicleDialogListener)活性;
            打破;
        }
        案例片断:{
            //发送回调事件到目标片段
            mListener =(DriverVehicleDialogListener)getTargetFragment();
            打破;
        }
        }
    }    @覆盖
    公共无效onActivityCreated(捆绑savedInstanceState){
        // TODO自动生成方法存根
        super.onActivityCreated(savedInstanceState);
        按钮btnAddDriverVehicle =(按钮)mView.findViewById(R.id.addDriverVehicleButton);        btnAddDriverVehicle.setOnClickListener(新View.OnClickListener(){            @覆盖
            公共无效的onClick(视图v){
                DatabaseHelper1 mOpenHelper =新DatabaseHelper1(getActivity());                尝试{
                    SQLiteDatabase分贝= mOpenHelper.getWritableDatabase();
                    db.delete(驱动程序,driver_number = 70,NULL);
                  }赶上(的SQLException E){                  }
            }
        });
    }    @覆盖
    公共对话框onCreateDialog(捆绑savedInstanceState){
        super.onSaveInstanceState(savedInstanceState);        捆绑ARGS = getArguments();        INT titleResource = args.getInt(ARG_TITLE_RESOURCE);
        的DialogType =的DialogType(的DialogType)args.getSerializable(ARG_DIALOG_TYPE);        如果(args.containsKey(ARG_SET_DRIVER)){
            mDrivers = args.getLongArray(ARG_SET_DRIVER);
        }        如果(args.containsKey(ARG_SET_VEHICLE)){
            mVehicles = args.getLongArray(ARG_SET_VEHICLE);
        }        MVIEW = LayoutInflater.from(getActivity())膨胀(R.layout.driver_vehicle_dialog,NULL);        如果((==的DialogType DialogType.DRIVER_SPINNER)||(==的DialogType DialogType.DRIVER_VEHICLE_SPINNER)){
            driversSpinner =(微调)mView.findViewById(R.id.driversSpinner);
            vehiclesSpinner =(微调)mView.findViewById(R.id.vehiclesSpinner);            driversSpinner.setVisibility(View.VISIBLE);
            mDriversAdapter =新SimpleCursorAdapter(getActivity(),R.layout.driver_listview_row,空,新的String [] {ConsoleContract.Drivers.DRIVER_NUMBER,
                    ConsoleContract.Drivers.DRIVER_NAME},新的INT [] {R.id.driver_number,R.id.driver_name},0);
            driversSpinner.setAdapter(mDriversAdapter);
            driversSpinner.setOnItemSelectedListener(本);
        }        如果((==的DialogType DialogType.VEHICLE_SPINNER)||(==的DialogType DialogType.DRIVER_VEHICLE_SPINNER)){
            vehiclesSpinner.setVisibility(View.VISIBLE);
            mVehiclesAdapter =新SimpleCursorAdapter(getActivity(),R.layout.vehicle_listview_row,空,新的String [] {ConsoleContract.Vehicles.VEHICLE_NUMBER,
                    ConsoleContract.Vehicles.VEHICLE_VIN},新的INT [] {R.id.vehicle_number,R.id.vehicle_vin},0);
            vehiclesSpinner.setAdapter(mVehiclesAdapter);
            vehiclesSpinner.setOnItemSelectedListener(本);
        }        // prepare装载机。无论是与现有的重新连接,或者开始一个新的。
        。getLoaderManager()initLoader(DRIVERS_LOADER,空,这一点);
        。getLoaderManager()initLoader(VEHICLES_LOADER,空,这一点);        AlertDialog.Builder建设者=新AlertDialog.Builder(getActivity());        builder.setView(MVIEW);        如果(titleResource == 0){
            builder.setMessage(选择驾驶员和车辆);
        }其他{
            builder.setMessage(的getString(titleResource));
        }        builder.setPositiveButton(android.R.string.ok,新OnClickListener(){
            公共无效的onClick(DialogInterface对话,诠释它){
                mListener.onDialogPositiveClick(mDrivers,mVehicles);
            }
        });        builder.setNegativeButton(android.R.string.cancel,NULL);        返回builder.create();
    }    私有静态类DatabaseHelper1扩展SQLiteOpenHelper {
        私有静态最后弦乐DATABASE_NAME =test.db的;
        私有静态最终诠释DATABASE_VERSION = 1;        DatabaseHelper1(上下文的背景下){
            超(背景下,DATABASE_NAME,空,DATABASE_VERSION);
        }        @覆盖
        公共无效的onCreate(SQLiteDatabase DB){
        }        @覆盖
        公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
        }
    }    @覆盖
    公共无效onDetach(){
        super.onDetach();
        mListener = NULL;
    }    //这些联系人行,我们将检索。
    静态最后的String [] = DRIVERS_SUMMARY_PROJECTION新的String [] {ConsoleContract.Drivers._ID,ConsoleContract.Drivers.DRIVER_ID,ConsoleContract.Drivers.DRIVER_NUMBER,
            ConsoleContract.Drivers.DRIVER_NAME};
    静态最后的String [] = VEHICLES_SUMMARY_PROJECTION新的String [] {ConsoleContract.Vehicles._ID,ConsoleContract.Vehicles.VEHICLE_ID,ConsoleContract.Vehicles.VEHICLE_NUMBER,
            ConsoleContract.Vehicles.VEHICLE_VIN};    @覆盖
    公共装载机<&光标GT; onCreateLoader(INT ID,捆绑参数){
        //这就是所谓当一个新的Loader需要创建。这个
        //样品只有一个装载机,所以我们不关心的ID。
        //首先,选择基本URI取决于我们是否使用
        //当前过滤。
        乌里基本URI = NULL;
        串选择= NULL,中将sortOrder = NULL;
        的String []投影= NULL;        开关(ID){
        案例DRIVERS_LOADER:
            基本URI = ConsoleContract.Drivers.CONTENT_URI;
            选择=((+ Drivers.DRIVER_NAME +NOT NULL)AND(+ Drivers.DRIVER_NAME +='')!);
            中将sortOrder = Drivers.DRIVER_NUMBER;
            投影= DRIVERS_SUMMARY_PROJECTION;
            打破;
        案例VEHICLES_LOADER:
            基本URI = ConsoleContract.Vehicles.CONTENT_URI;
            选择=((+ Vehicles.VEHICLE_NUMBER +NOT NULL)AND(+ Vehicles.VEHICLE_NUMBER +='')!);
            中将sortOrder = Vehicles.VEHICLE_NUMBER;
            投影= VEHICLES_SUMMARY_PROJECTION;
            打破;
        }        返回新CursorLoader(getActivity(),基本URI,投影,选择,空,中将sortOrder);
    }    @覆盖
    公共无效onLoadFinished(装载机<&光标GT;装载机,游标数据){
        //交换新的光标(该框架将采取关闭照顾
        //老光标一旦我们回来。)        INT ID = loader.getId();
        MatrixCursor newCursor = NULL;        开关(ID){
        案例DRIVERS_LOADER:
            newCursor =新MatrixCursor(DRIVERS_SUMMARY_PROJECTION);
            打破;
        案例VEHICLES_LOADER:
            newCursor =新MatrixCursor(VEHICLES_SUMMARY_PROJECTION);
            打破;
        }        newCursor.addRow(新的String [] {0,0,,});
        光标[]光标= {newCursor,数据};
        光标mergedCursor =新MergeCursor(光标);        开关(ID){
        案例DRIVERS_LOADER:
            mDriversAdapter.swapCursor(mergedCursor);
            打破;
        案例VEHICLES_LOADER:
            mVehiclesAdapter.swapCursor(mergedCursor);
            打破;
        }    }    @覆盖
    公共无效onLoaderReset(装载机<&光标GT;装载机){
        //这就是所谓的当提供给onLoadFinished一个光标()
        //上述即将被关闭。我们需要确保我们没有
        //不再使用它。        INT ID = loader.getId();        开关(ID){
        案例DRIVERS_LOADER:
            mDriversAdapter.swapCursor(NULL);
            打破;
        案例VEHICLES_LOADER:
            mVehiclesAdapter.swapCursor(NULL);
            打破;
        }
    }    @覆盖
    公共无效onItemSelected(适配器视图<>母公司,观景,INT POS,长I​​D){
        如果(parent.getId()== R.id.driversSpinner){
           mDriver = ID;
        }其他{
           mVehicle = ID;
        }
    }    @覆盖
    公共无效onNothingSelected(适配器视图<>母公司){
    }
}


解决方案

请确保你的的ContentProvider 来调用有NotifyChange()插入物内的方法,删除和更新的方法。

下面从所著的Grokking的Andr​​oid博客

 公众开放的插入(URI URI,ContentValues​​值){
   如果(URI_MATCHER.match(URI)!= LENTITEM_LIST){
      抛出新抛出:IllegalArgumentException(不支持的URI插入:+ URI);
   }
   长ID = db.insert(DBSchema.TBL_ITEMS,空,价值);
   如果(ID大于0){
      //更改通知所有侦听器,并返回itemUri:
      乌里itemUri = ContentUris.withAppendedId(URI,ID);
      。的getContext()getContentResolver()有NotifyChange(itemUri,NULL);
      返回itemUri;
   }
   // s.th.出错:
   抛出新的SQLException(问题,同时插入+ DBSchema.TBL_ITEMS +,URI:+ URI); //这里用另一个异常!
}

相反你的装载机将无法听DB的变化。

I have a DialogFragment that I'm working on to display two spinners, side by side, one displays a list of drivers, the other a list of vehicles.

The data to populate these spinners is retrieved from a sqlite database. I am trying to use a LoaderManager to keep the spinners updated or in sync with the database tables, (drivers and vehicles).

When I add/delete/edit a record in either the drivers table or vehicles table in the database, the spinners don't get updated, the driver or vehicle remains unchanged in the spinner.

I'm not sure what I'm missing because I thought LoaderManager is supposed to keep the lists updated or in sync with the database tables automatically right?

I created a button called addDriverVehicle() which is supposed to allow the user to add another driver/vehicle in the future but for now I'm using it as a test to delete a driver to kind of simulate the database tables changing just so i can see if the spinner gets updated automatically but it's not happening. The record is being deleted but the spinner continues to show it.

    public class DriverVehiclePickersDialogFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Cursor>, OnItemSelectedListener {

    public static final String ARG_LISTENER_TYPE = "listenerType";
    public static final String ARG_DIALOG_TYPE = "dialogType";
    public static final String ARG_TITLE_RESOURCE = "titleResource";
    public static final String ARG_SET_DRIVER = "setDriver";
    public static final String ARG_SET_VEHICLE = "setVehicle";

    private static final int DRIVERS_LOADER = 0;
    private static final int VEHICLES_LOADER = 1;

    private DriverVehicleDialogListener mListener;

    // These are the Adapter being used to display the driver's and vehicle's data.
    SimpleCursorAdapter mDriversAdapter, mVehiclesAdapter;

    // Define Dialog view
    private View mView;

    // Store Driver and Vehicle Selected
    private long[] mDrivers, mVehicles;

    // Spinners Containing Driver and Vehicle List
    private Spinner driversSpinner;
    private Spinner vehiclesSpinner;

    private static enum ListenerType {
        ACTIVITY, FRAGMENT
    }

    public static enum DialogType {
        DRIVER_SPINNER, VEHICLE_SPINNER, DRIVER_VEHICLE_SPINNER
    }

    public interface DriverVehicleDialogListener {
        public void onDialogPositiveClick(long[] mDrivers, long[] mVehicles);
    }

    public DriverVehiclePickersDialogFragment() {
        // Empty Constructor
        Log.d("default", "default constructor ran");
    }

    public static DriverVehiclePickersDialogFragment newInstance(DriverVehicleDialogListener listener, Bundle dialogSettings) {
        final DriverVehiclePickersDialogFragment instance;

        if (listener instanceof Activity) {
            instance = createInstance(ListenerType.ACTIVITY, dialogSettings);
        } else if (listener instanceof Fragment) {
            instance = createInstance(ListenerType.FRAGMENT, dialogSettings);
            instance.setTargetFragment((Fragment) listener, 0);
        } else {
            throw new IllegalArgumentException(listener.getClass() + " must be either an Activity or a Fragment");
        }

        return instance;
    }

    private static DriverVehiclePickersDialogFragment createInstance(ListenerType listenerType, Bundle dialogSettings) {
        DriverVehiclePickersDialogFragment fragment = new DriverVehiclePickersDialogFragment();

        if (!dialogSettings.containsKey(ARG_LISTENER_TYPE)) {
            dialogSettings.putSerializable(ARG_LISTENER_TYPE, listenerType);
        }

        if (!dialogSettings.containsKey(ARG_DIALOG_TYPE)) {
            dialogSettings.putSerializable(ARG_DIALOG_TYPE, DialogType.DRIVER_VEHICLE_SPINNER);
        }

        if (!dialogSettings.containsKey(ARG_TITLE_RESOURCE)) {
            dialogSettings.putInt(ARG_TITLE_RESOURCE, 0);
        }

        fragment.setArguments(dialogSettings);
        return fragment;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // Find out how to get the DialogListener instance to send the callback events to
        Bundle args = getArguments();
        ListenerType listenerType = (ListenerType) args.getSerializable(ARG_LISTENER_TYPE);

        switch (listenerType) {
        case ACTIVITY: {
            // Send callback events to the hosting activity
            mListener = (DriverVehicleDialogListener) activity;
            break;
        }
        case FRAGMENT: {
            // Send callback events to the "target" fragment
            mListener = (DriverVehicleDialogListener) getTargetFragment();
            break;
        }
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
        Button btnAddDriverVehicle = (Button) mView.findViewById(R.id.addDriverVehicleButton);

        btnAddDriverVehicle.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                DatabaseHelper1 mOpenHelper = new DatabaseHelper1(getActivity());

                try {
                    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
                    db.delete("drivers", " driver_number = 70", null);
                  } catch (SQLException e) {

                  }
            }
        });         
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);

        Bundle args = getArguments();

        int titleResource = args.getInt(ARG_TITLE_RESOURCE);
        DialogType dialogType = (DialogType) args.getSerializable(ARG_DIALOG_TYPE);

        if (args.containsKey(ARG_SET_DRIVER)) {
            mDrivers = args.getLongArray(ARG_SET_DRIVER);
        }

        if (args.containsKey(ARG_SET_VEHICLE)) {
            mVehicles = args.getLongArray(ARG_SET_VEHICLE);
        }

        mView = LayoutInflater.from(getActivity()).inflate(R.layout.driver_vehicle_dialog, null);

        if ((dialogType == DialogType.DRIVER_SPINNER) || (dialogType == DialogType.DRIVER_VEHICLE_SPINNER)) {
            driversSpinner = (Spinner) mView.findViewById(R.id.driversSpinner);
            vehiclesSpinner = (Spinner) mView.findViewById(R.id.vehiclesSpinner);

            driversSpinner.setVisibility(View.VISIBLE);
            mDriversAdapter = new SimpleCursorAdapter(getActivity(), R.layout.driver_listview_row, null, new String[] { ConsoleContract.Drivers.DRIVER_NUMBER,
                    ConsoleContract.Drivers.DRIVER_NAME }, new int[] { R.id.driver_number, R.id.driver_name }, 0);
            driversSpinner.setAdapter(mDriversAdapter);
            driversSpinner.setOnItemSelectedListener(this);
        }

        if ((dialogType == DialogType.VEHICLE_SPINNER) || (dialogType == DialogType.DRIVER_VEHICLE_SPINNER)) {
            vehiclesSpinner.setVisibility(View.VISIBLE);
            mVehiclesAdapter = new SimpleCursorAdapter(getActivity(), R.layout.vehicle_listview_row, null, new String[] { ConsoleContract.Vehicles.VEHICLE_NUMBER,
                    ConsoleContract.Vehicles.VEHICLE_VIN }, new int[] { R.id.vehicle_number, R.id.vehicle_vin }, 0);
            vehiclesSpinner.setAdapter(mVehiclesAdapter);
            vehiclesSpinner.setOnItemSelectedListener(this);
        }

        // Prepare the loader. Either re-connect with an existing one, or start a new one.
        getLoaderManager().initLoader(DRIVERS_LOADER, null, this);
        getLoaderManager().initLoader(VEHICLES_LOADER, null, this);

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        builder.setView(mView);

        if (titleResource == 0) {
            builder.setMessage("Select Driver and Vehicle");
        } else {
            builder.setMessage(getString(titleResource));
        }

        builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                mListener.onDialogPositiveClick(mDrivers, mVehicles);
            }
        });

        builder.setNegativeButton(android.R.string.cancel, null);   

        return builder.create();
    }

    private static class DatabaseHelper1 extends SQLiteOpenHelper {
        private static final String DATABASE_NAME = "test.db";
        private static final int DATABASE_VERSION = 1;

        DatabaseHelper1(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    // These are the Contacts rows that we will retrieve.
    static final String[] DRIVERS_SUMMARY_PROJECTION = new String[] { ConsoleContract.Drivers._ID, ConsoleContract.Drivers.DRIVER_ID, ConsoleContract.Drivers.DRIVER_NUMBER,
            ConsoleContract.Drivers.DRIVER_NAME };
    static final String[] VEHICLES_SUMMARY_PROJECTION = new String[] { ConsoleContract.Vehicles._ID, ConsoleContract.Vehicles.VEHICLE_ID, ConsoleContract.Vehicles.VEHICLE_NUMBER,
            ConsoleContract.Vehicles.VEHICLE_VIN };

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // This is called when a new Loader needs to be created. This
        // sample only has one Loader, so we don't care about the ID.
        // First, pick the base URI to use depending on whether we are
        // currently filtering.
        Uri baseUri = null;
        String select = null, sortOrder = null;
        String[] projection = null;

        switch (id) {
        case DRIVERS_LOADER:
            baseUri = ConsoleContract.Drivers.CONTENT_URI;
            select = "((" + Drivers.DRIVER_NAME + " NOT NULL) AND (" + Drivers.DRIVER_NAME + " != '' ))";
            sortOrder = Drivers.DRIVER_NUMBER;
            projection = DRIVERS_SUMMARY_PROJECTION;
            break;
        case VEHICLES_LOADER:
            baseUri = ConsoleContract.Vehicles.CONTENT_URI;
            select = "((" + Vehicles.VEHICLE_NUMBER + " NOT NULL) AND (" + Vehicles.VEHICLE_NUMBER + " != '' ))";
            sortOrder = Vehicles.VEHICLE_NUMBER;
            projection = VEHICLES_SUMMARY_PROJECTION;
            break;
        }

        return new CursorLoader(getActivity(), baseUri, projection, select, null, sortOrder);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // Swap the new cursor in. (The framework will take care of closing the
        // old cursor once we return.)

        int id = loader.getId();
        MatrixCursor newCursor = null;

        switch (id) {
        case DRIVERS_LOADER:
            newCursor = new MatrixCursor(DRIVERS_SUMMARY_PROJECTION);
            break;
        case VEHICLES_LOADER:
            newCursor = new MatrixCursor(VEHICLES_SUMMARY_PROJECTION);
            break;
        }

        newCursor.addRow(new String[] { "0", "0", "", "" });
        Cursor[] cursors = { newCursor, data };
        Cursor mergedCursor = new MergeCursor(cursors);

        switch (id) {
        case DRIVERS_LOADER:
            mDriversAdapter.swapCursor(mergedCursor);
            break;
        case VEHICLES_LOADER:
            mVehiclesAdapter.swapCursor(mergedCursor);
            break;
        }

    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // This is called when the last Cursor provided to onLoadFinished()
        // above is about to be closed. We need to make sure we are no
        // longer using it.

        int id = loader.getId();

        switch (id) {
        case DRIVERS_LOADER:
            mDriversAdapter.swapCursor(null);
            break;
        case VEHICLES_LOADER:
            mVehiclesAdapter.swapCursor(null);
            break;
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
        if (parent.getId() == R.id.driversSpinner) {
           mDriver = id;
        } else {
           mVehicle = id;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }
}

解决方案

Make sure in your ContentProvider to call the notifyChange() method inside the insert, delete and update methods.

Here a snippet taken from Grokking Android Blog

public Uri insert(Uri uri, ContentValues values) { 
   if (URI_MATCHER.match(uri) != LENTITEM_LIST) { 
      throw new IllegalArgumentException("Unsupported URI for insertion: " + uri); 
   } 
   long id = db.insert(DBSchema.TBL_ITEMS, null, values); 
   if (id > 0) { 
      // notify all listeners of changes and return itemUri: 
      Uri itemUri = ContentUris.withAppendedId(uri, id); 
      getContext().getContentResolver().notifyChange(itemUri, null); 
      return itemUri; 
   } 
   // s.th. went wrong: 
   throw new SQLException("Problem while inserting into " + DBSchema.TBL_ITEMS + ", uri: " + uri); // use another exception here!!!
} 

Conversely your Loader won't "heard" DB changes.

这篇关于装载机不加载数据sqlite的数据发生变化时,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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