安卓:片段时,SQLite和装载机装载机、片段、SQLite

2023-09-05 08:45:24 作者:把你的爱借我

所以,我已经到了一个地步,我需要实现SQLite数据库为我的应用程序。 继在忙codeR指南Android开发我已经创建了一个扩展了DatabaseHelper类 SQLiteOpenHelper

So I've come to a point where I need to implement an SQLite database for my app. Following "The Busy Coder's guide to Android Development" I have created a DatabaseHelper class that extends SQLiteOpenHelper.

我的一个用例是对数据库运行一个查询并显示在的ListView A 片段中的结果(我用从支持库片段)。

One of my use cases is to run a query against the database and display the results on a ListView within a Fragment (I use fragments from the support library).

据我了解,使用 managedQuery()是不是真的合适,即使它是它是不是由于这样的事实,一些逻辑封装内部推荐这种方法是在主线程中实际执行,特别是 REQUERY()这在我的理解中执行时,活动是重新启动。

From what I understand, using managedQuery() is not really appropriate and even if it were it isn't recommended due to the fact that some of the logic encapsulated inside this method is actually executed on the main thread, specifically reQuery() which to my understanding is performed when the Activity is restarted.

所以,我一直在试图结识装载机类的第一次,只有看到这一点:

So I've been trying to get acquainted with the Loader class for the first time, only to see this:

唯一提供的具体实施装载机是CursorLoader,那就是只对一个ContentProvider的使用

我最初的想法是要实现从获得访问它自己的内容提供商也许prevent其他应用程序,然后我读通过以下的的ContentProvider 文档developer.android.com:

My initial thought was to implement my own content provider and perhaps prevent other apps from getting access to it, then I read the following in the ContentProvider documentation via developer.android.com:

你并不需要一个供应商使用SQLite数据库,如果使用是完全属于你自己的应用程序。

我也一直在玩这样的:

https://github.com/commonsguy/cwac-loaderex

不过,我不熟悉这个项目,不知道是否可以在生产环境中使用。

Yet I am not familiar with this project, and not sure if it can be used on a production environment.

所以,现在所有我能想到的是创造我的片段中一群的AsyncTask 实例和管理它们的生命周期适当,确保他们取消了在需要时和诸如此类的东西。

So, right now all I can think of is creating a bunch of AsyncTask instances within my Fragment and manage their lifecycle appropriately, make sure they're cancelled whenever needed and whatnot.

是否还有其他选择吗?

推荐答案

您可以以执行其他异步工作,如加载直接从您的数据库扩展Loader类。

You can extend Loader class in order to perform other Async work such as loading directly from your DB.

这里是一个很好的例子

编辑:添加装载机使用的一个更好的例子

added A better example of Loader usage.

终于设法找到真正帮助我理解的事情是如何工作的教程。

Finally managed to find the tutorial that really helped me understand how things work.

通过扩展类加载器,你可以避免与内容观察员和搞乱它很容易实现的(最后) 这需要采取在code中的修改

By extending the loader class you can avoid messing with content observers and its quite easy to implement (at last) the modifications that need to be taken in your code are

添加实施 LoaderManager.LoaderCallbacks&LT; D​​&GT; ,其中 D 是您的数据列表(片段1) 创建您的装载机类,复制片段2,并且从DB 添加数据的加载 最后调用装载机1呼吁初始化,然后刷新重启电话。 (片段2及3) Add implementation of LoaderManager.LoaderCallbacks<D>, where D is your data list (snippet 1) Create your loader class, copy snippet 2, and add the loading of your data from the DB Finally call the loaders 1 call for init and then for refreshing the restart call. (snippet 2 & 3)

片段1:的如何为链接装载机与您的片段:

Snippet 1: How to "link" the loader with your fragment:

public static class AppListFragment extends ListFragment implements
      LoaderManager.LoaderCallbacks<List<SampleItem>> {

  public Loader<List<SampleItem>> onCreateLoader(int id, Bundle args) { 
     //...
     return new SampleLoader (getActivity());
  }

  public void onLoadFinished(Loader<List<SampleItem>> loader, List<SampleItem> data) {
    // ... 
     mAdapter.setData(data);

     if (isResumed()) {
       setListShown(true);
     } else {
       setListShownNoAnimation(true);
     }
    // ... 
 }

  public void onLoaderReset(Loader<List<SampleItem>> loader) { 
    // ... 
    mAdapter.setData(null);
    // ... 
  }

  /* ... */
}

片段2:的自定义装载机的模式:(我有双重评价观察者的事情,因为我认为这是相当困难的,从一开始实现它,你可以简单的回忆,而不必用自动清爽搞乱)装载机

Snippet 2: Schema of your custom loader: (I have double commented the observer things as I believe that it is quite difficult to implement it from the beginning and you can simple recall the loader without messing with that automated refreshing)

public class SampleLoader extends AsyncTaskLoader<List<SampleItem>> {

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

  public SampleLoader(Context ctx) {
    // Loaders may be used across multiple Activitys (assuming they aren't
    // bound to the LoaderManager), so NEVER hold a reference to the context
    // directly. Doing so will cause you to leak an entire Activity's context.
    // The superclass constructor will store a reference to the Application
    // Context instead, and can be retrieved with a call to getContext().
    super(ctx);
  }

  /****************************************************/
  /** (1) A task that performs the asynchronous load **/
  /****************************************************/

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

    // TODO: Perform the query here and add the results to 'data'.

    return data;
  }

  /********************************************************/
  /** (2) Deliver the results to the registered listener **/
  /********************************************************/

  @Override
  public void deliverResult(List<SampleItem> data) {
    if (isReset()) {
      // The Loader has been reset; ignore the result and invalidate the data.
      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<SampleItem> 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);
    }
  }

  /*********************************************************/
  /** (3) Implement the Loader’s state-dependent behavior **/
  /*********************************************************/

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

    // Begin monitoring the underlying data source.
    ////if (mObserver == null) {
      ////mObserver = new SampleObserver();
      // TODO: register the observer
    ////}

    //// takeContentChanged() can still be implemented if you want 
    ////     to mix your refreshing in that mechanism 
    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();
    }
  }

  @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();

    // 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) {
      // TODO: unregister the observer
     //// mObserver = null;
    ////}
  }

  @Override
  public void onCanceled(List<SampleItem> 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<SampleItem> 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.
  }

  /*********************************************************************/
  /** (4) Observer which receives notifications when the data changes **/
  /*********************************************************************/

  // NOTE: Implementing an observer is outside the scope of this post (this example
  // uses a made-up "SampleObserver" to illustrate when/where the observer should 
  // be initialized). 

  // The observer could be anything so long as it is able to detect content changes
  // and report them to the loader with a call to onContentChanged(). For example,
  // if you were writing a Loader which loads a list of all installed applications
  // on the device, the observer could be a BroadcastReceiver that listens for the
  // ACTION_PACKAGE_ADDED intent, and calls onContentChanged() on the particular 
  // Loader whenever the receiver detects that a new application has been installed.
  // Please don’t hesitate to leave a comment if you still find this confusing! :)
  ////private SampleObserver mObserver;
}

片段3:的如何调用装载机首次(只)

Snippet 3: How to call the loader for the first time (ONLY)

  // Initialize a Loader with an id. If the Loader with this id is not 
  // initialized before
  getLoaderManager().initLoader(LOADER_ID, null, this);

摘录4:的刷新数据(忆查询)

Snippet 4: For refreshing data (recalling the query)

 // Check if the loader exists and then restart it.
 if (getLoaderManager().getLoader(LOADER_ID) != null)
     getLoaderManager().restartLoader(LOADER_ID, null, this);

参考:的

片段1:装载机的使用,从这里 片段2:这里更多的信息和逻辑读取整个孔的文章 在片段3及4:只是装载机的使用。 Snippet 1 : usage of loader extracted from here Snippet 2 : here for more info and logic read throughout the hole article Snippet 3 & 4: are just loader usage.

全部$ C $这些C也由创作者上传到 github上

Full code of these is also uploaded by the creator on github

 
精彩推荐