装载程序不更新屏幕上的列表

时间:2017-09-07 04:53:08

标签: android runtime-error loader

Loader不更新屏幕上的列表。只有当我按下按钮并调用sampleLoader.onContentChanged()时,列表才会更新。他们的广播接收器也存在一些问题。当我第一次更改配置时,它会在下面给出此错误。并且还会在活动重新启动时更新配置更改。但是如果保持活动打开服务添加的数据,则在后台dosn中更新列表。

代码:实施LoaderCallback的主要活动

public class MainActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<List<DemoItem>>,ServiceCallbacks {

private static final String TAG = "MainActivityFragment";
private static final int LOADER_ID = 1;
Context context;
private UpdateServices myService;
private boolean bound = false;
MySQLiteHelper m;
SampleLoader sampleLoader;
CustomAdapter customAdapter;
ListView mList;
ArrayList<DemoItem> allList;
Button b1,b2;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    /**
     * This condition check saved instance if any and assign it
     */
   /*if (savedInstanceState != null) {
        sampleLoader = (SampleLoader) savedInstanceState.getSerializable("ObjectA");
        // check mObjectA == mObjectA.getObjectBList().get(0).getParent();

    }*/
    b1=(Button)findViewById(R.id.button);
    b2=(Button)findViewById(R.id.button1);
    m = new MySQLiteHelper(this);
    /**
     * This method initialize the Loader
     */
  sampleLoader = (SampleLoader) getLoaderManager().initLoader(LOADER_ID, null,this);

    mList = (ListView) findViewById(R.id.listView);
    allList = m.getAllItems();
    customAdapter = new CustomAdapter(this, allList);
    mList.setAdapter(customAdapter);
 final    ServiceConnection serviceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            // cast the IBinder and get MyService instance
            UpdateServices.LocalBinder binder = (UpdateServices.LocalBinder) service;
            myService = binder.getService();
            bound = true;
            myService.setCallbacks(MainActivity.this); // register
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            bound = false;
        }
    };
    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            add();
           // startService(new Intent(getApplicationContext(), UpdateServices.class));

        }
    });

    if(!isMyServiceRunning(UpdateServices.class)) {
        startService(new Intent(getApplicationContext(), UpdateServices.class));
    }
   // Intent intent = new Intent(getApplicationContext(), UpdateServices.class);
    //bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);


    b2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

           // stopService(new Intent(getApplicationContext(), UpdateServices.class));
            if (bound) {
                myService.setCallbacks(null); // unregister
                unbindService(serviceConnection);
                bound = false;
            }
        }
    });

}

public void add() {

    DemoItem d = new DemoItem();
    d.set("Fifty5Bytes", "Company");
    m.addItem(d);

    sampleLoader.onContentChanged();
}


@Override
public Loader<List<DemoItem>> onCreateLoader(int id, Bundle args) {
    Log.i(TAG, "onCreateLoader");
    sampleLoader = new SampleLoader(this);
    return sampleLoader;
}

@Override
public void onLoadFinished(Loader<List<DemoItem>> loader, List<DemoItem> cursor) {
    Log.i(TAG, "onLoadFinished " + cursor.size());
    allList.clear();
    allList.addAll(m.getAllItems());
    customAdapter.notifyDataSetChanged();
    mList.setSelection(allList.size() - 1);
}

@Override
public void onLoaderReset(Loader<List<DemoItem>> loader) {
   // sampleLoader = null;
    Log.i(TAG, "onLoaderReset");
}
/* @Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("ObjectA", sampleLoader);
}*/


@Override
public void doSomething() {
    Log.i("do something","do something called");
    sampleLoader.onContentChanged();
}
@Override
protected void onStop(){
    try {
        super.onStop();
    }catch (Exception e){}
    Log.i(TAG, "on stop called");
}

/** Lifecycle method: The final call received before the activity is destroyed. */
@Override
protected void onDestroy(){
    try{
    super.onDestroy();}
    catch (Exception e){}

    Log.i(TAG,"on destroy called");
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}
}

Loader Class

public class SampleLoader extends AsyncTaskLoader<List<DemoItem>> implements Serializable {

public static final String TAG = "SampleLoader";

/** We hold a reference to the Loader’s data here.*/
private List<DemoItem> mData;

Context ctx;

public SampleLoader(Context ctx) {
    super(ctx);
    this.ctx = ctx;
    ctx.registerReceiver(mObserver, new IntentFilter("my-event"));
}

@Override
public List<DemoItem> loadInBackground() {
    // This method is called on a background thread and should generate a
    // new set of data to be delivered back to the client.

    MySQLiteHelper mySQLiteHelper = new MySQLiteHelper(ctx);
    List<DemoItem> allItems = mySQLiteHelper.getAllItems();

    Log.i(TAG,"Size : " + allItems.size());

    return allItems;
}

@Override
public void deliverResult(List<DemoItem> data) {
    if (isReset()) {
        // The Loader has been reset;
        releaseResources(data);
        return;
    }

    // Hold a reference to the old data so it doesn't get garbage collected.
    // We must protect it until the new data has been delivered.
    List<DemoItem> oldData = mData;
    mData = data;

    if (isStarted()) {
        // If the Loader is in a started state, deliver the results to the
        // client. The superclass method does this for us.
        super.deliverResult(data);
    }

    // Invalidate the old data as we don't need it any more.
    if (oldData != null && oldData != data) {
        releaseResources(oldData);
    }
}

@Override
protected void onStartLoading() {
    if (mData != null) {
        // Deliver any previously loaded data immediately.
        deliverResult(mData);
    }

    if (takeContentChanged() || mData == null) {
        // When the observer detects a change, it should call onContentChanged()
        // on the Loader, which will cause the next call to takeContentChanged()
        // to return true. If this is ever the case (or if the current data is
        // null), we force a new load.
        forceLoad();
        Intent intent = new Intent("my-event");
        intent.putExtra("message", "message");
        getContext().sendBroadcast(intent);
    }
}

@Override
protected void onStopLoading() {
    // The Loader is in a stopped state, so we should attempt to cancel the
    // current load (if there is one).
    cancelLoad();

    // Note that we leave the observer as is. Loaders in a stopped state
    // should still monitor the data source for changes so that the Loader
    // will know to force a new load if it is ever started again.
}

@Override
protected void onReset() {
    // Ensure the loader has been stopped.
    onStopLoading();
    Log.i("Onreset","Loader reset method called");
    // At this point we can release the resources associated with 'mData'.
    if (mData != null) {
        releaseResources(mData);
        mData = null;
    }

    // The Loader is being reset, so we should stop monitoring for changes.
    if (mObserver != null) {
        try {
            getContext().unregisterReceiver(mObserver);
        } catch (Exception e) {
            e.printStackTrace();
        }
        mObserver = null;
    }
}

@Override
public void onCanceled(List<DemoItem> data) {
    // Attempt to cancel the current asynchronous load.
    super.onCanceled(data);

    // The load has been canceled, so we should release the resources
    // associated with 'data'.
    releaseResources(data);
}

private void releaseResources(List<DemoItem> data) {
    // For a simple List, there is nothing to do. For something like a Cursor, we
    // would close it in this method. All resources associated with the Loader
    // should be released here.
}

private BroadcastReceiver mObserver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Extract data included in the Intent
        //String message = intent.getStringExtra("message");
        Log.d("receiver", "Got message: ");
    }
};
 }

错误:

Activity com.aclass.asynctaskloader_01.MainActivity has leaked IntentReceiver com.aclass.asynctaskloader_01.SampleLoader$1@75cf002 that was originally registered here. Are you missing a call to unregisterReceiver()?
                                                                           android.app.IntentReceiverLeaked: Activity com.aclass.asynctaskloader_01.MainActivity has leaked IntentReceiver com.aclass.asynctaskloader_01.SampleLoader$1@75cf002 that was originally registered here. Are you missing a call to unregisterReceiver()?
                                                                               at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:918)
                                                                               at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:719)
                                                                               at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1172)
                                                                               at android.app.ContextImpl.registerReceiver(ContextImpl.java:1152)
                                                                               at android.app.ContextImpl.registerReceiver(ContextImpl.java:1146)
                                                                               at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:554)
                                                                               at com.aclass.asynctaskloader_01.SampleLoader.<init>(SampleLoader.java:29)
                                                                               at com.aclass.asynctaskloader_01.MainActivity.onCreateLoader(MainActivity.java:125)
                                                                               at android.app.LoaderManagerImpl.createLoader(LoaderManager.java:546)
                                                                               at android.app.LoaderManagerImpl.createAndInstallLoader(LoaderManager.java:555)
                                                                               at android.app.LoaderManagerImpl.initLoader(LoaderManager.java:609)
                                                                               at com.aclass.asynctaskloader_01.MainActivity.onCreate(MainActivity.java:59)
                                                                               at android.app.Activity.performCreate(Activity.java:6251)
                                                                               at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                                               at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                               at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                                               at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                               at android.os.Looper.loop(Looper.java:148)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

错误2

IllegalArgumentException: Receiver not registered: 
com.aclass.asynctaskloader_01.SampleLoader$1@4c0db59
09-07 12:39:07.496 22126-22126/com.aclass.asynctaskloader_01 W/System.err:     
at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:780)
09-07 12:39:07.496 22126-22126/com.aclass.asynctaskloader_01 W/System.err:     
at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1195)
09-07 12:39:07.496 22126-22126/com.aclass.asynctaskloader_01 W/System.err:     
at 
android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:576)
09-07 12:39:07.496 22126-22126/com.aclass.asynctaskloader_01 W/System.err:     
at com.aclass.asynctaskloader_01.SampleLoader.onReset(SampleLoader.java:116)

0 个答案:

没有答案