标签: android-loadermanager

Android FragmentPagerAdapter 与 LoaderManager

我有一个带有 ViewPager 和 FragmentPagerAdapter 的 FragmentActivity。

ViewPager 中的每个片段都需要从 Web 服务加载数据。我已经编写了 LoaderManager/自定义 Loaders 来执行 Web 服务调用、解析 XML 等,这些工作正常。

有两种可能的设计来管理加载和片段。

1) 代表片段管理加载的主要活动。

该片段回调主 FragmentActivity 请求其数据。该活动检查该数据的加载程序是否已在运行,如果没有,则创建一个加载程序并执行加载。

在这种情况下,我如何告诉片段数据已加载并准备好绘制。我使用的是自定义加载器而不是简单光标,因此片段将从对象实例填充其文本视图等,因此必须告知对象何时已填充。

当您在 getItem 中实例化片段时,FragmentPagerAdapter 似乎不允许您为片段分配标签或 Id。如何从 FragmentActivity 中找到片段并告诉它绘制其数据?

2) 每个片段管理自己的加载。

Fragment初始化自己的Loader,每个fragment都有自己的onCreateLoader/onLoaderFinish等。

我在这里遇到的问题是,如果用户在加载程序运行时离开该页面,则片段似乎被破坏(有时)。因此,不会调用 onLoaderFinished,并且片段无法告诉主活动它已完成 - 主活动正在控制操作栏中的进度指示器 (setProgressBarInminatedVisibility)。

那么,当您有一个 FragmentPagerAdapter(一个具有多个需要自己的加载器的页面的 ViewPager)时,最好的设计模式是什么?

我遇到的另一个问题是使用 getSupportLoaderManager 检查是否有任何加载程序正在运行。我从 onLoadFinished 中调用它。如果没有加载程序运行,我可以隐藏进度指示器。然而,即使所有加载器都已完成,hasRunningLoaders 有时也会返回 true。

        LoaderManager lm = getSupportLoaderManager();

    // If the loader is not already running, start it...
    if (! lm.hasRunningLoaders()) {
        setProgressBarIndeterminateVisibility(Boolean.FALSE);
    }
Run Code Online (Sandbox Code Playgroud)

非常感谢您提供任何建议或为我指明一些不错的样本的方向。

塔·马丁.

android android-fragments android-viewpager android-loadermanager

5
推荐指数
1
解决办法
2306
查看次数

错误:java.lang.NullPointerException at android.support.v4.content.Loader

我想LoaderManager在我的应用程序中实施以减少启动时间正如您在此处看到的,但在该线程中实施建议后,我收到以下错误initLoader(int, Bundle, LoaderManager.LoaderCallbacks) in the type LoaderManager is not applicable for the arguments (int, null, MainActivity)。在这里搜索后,我发现对于第二个错误的解决方案在这里。但是在实施了后来的建议之后,现在我收到了错误java.lang.NullPointerException at android.support.v4.content.Loader。我正在提供我目前拥有的代码,谁能告诉我,我该如何解决这个问题

完整代码可以在 这里看到

原木猫

10-03 20:11:34.849: E/AndroidRuntime(2968): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.sms.it/com.test.sms.it.MainActivity}: java.lang.NullPointerException
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.os.Looper.loop(Looper.java:123)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.main(ActivityThread.java:3683)
10-03 20:11:34.849: E/AndroidRuntime(2968): …
Run Code Online (Sandbox Code Playgroud)

android android-loadermanager android-support-library

5
推荐指数
1
解决办法
4475
查看次数

android getContentResolver().notifyChange()不重启我的加载器

代码:

首先是我的Uris

public static final String PACKAGE    = "my.url.contentprovider";

public static final String TABLE_NAME = "NetworkTransaction";

public static final String AUTHORITY  = PACKAGE + ".NetTransContentProvider";

public static final Uri BASE_URI = Uri.parse("content://"+AUTHORITY);

public static final Uri CONTENT_URI_ANY_OBSERVER  = Uri.withAppendedPath(BASE_URI,TABLE_NAME+"/*");

public static final Uri CONTENT_URI_FIND_BY_ID  = Uri.withAppendedPath(BASE_URI,TABLE_NAME+"/FIND/ID");

public static final Uri CONTENT_URI_INSERT_OR_REPLACE_BY_ID    = Uri.withAppendedPath(BASE_URI,TABLE_NAME+"/INSERT/REPLACE/ID"); 

public static final Uri CONTENT_URI_INSERT_BY_ID   = Uri.withAppendedPath(BASE_URI,TABLE_NAME+"/INSERT/ID"); 
Run Code Online (Sandbox Code Playgroud)

和我的活动代码加载器:

@Override
protected void onResume() {
    super.onResume();
getSupportLoaderManager().restartLoader(NET_TRANS_LOADER_ID,mBundle,this).forceLoad();

}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
    Uri uri = …
Run Code Online (Sandbox Code Playgroud)

android android-contentresolver android-contentprovider android-loadermanager android-loader

4
推荐指数
1
解决办法
2041
查看次数

如何在Fragments中使用getSupportLoaderManager()?

我想将API中的信息加载到Fragment.

我使用getSupportLoaderManager()但发生错误:

无法解析方法:getSupportLoaderManager()

我搜索这个用途,onActivityCreated()但我有NullPointerException.

你能帮我解决一下这个问题吗?

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;

public class Business extends Fragment implements LoaderManager.LoaderCallbacks<String> {

    ListView listView;   

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_business, container, false);
        listView = view.findViewById(R.id.list_item);

        getSupportLoaderManager().initLoader(0, null, getContext()).forceLoad();
        return view;
    }

    @Override
    public Loader<String> onCreateLoader(int id, Bundle args) {
        return null; …
Run Code Online (Sandbox Code Playgroud)

java android android-fragments android-loadermanager

4
推荐指数
1
解决办法
1162
查看次数

Android LoaderManager和CursorLoader混淆

我试图将我的Android应用程序转换为使用LoaderManager和CursorLoader.基本上,我有一个包含ADDRESS列和DISTANCE列的SQLite数据库,我想将列值加载到ListView行中.

现在,我已经做了很多研究,所有内容都指向了这个教程:http://mobile.tutsplus.com/tutorials/android/android-sdk_content-providers/

这是一个很好的教程,但有几件事我还是不明白.主要是,如何构造传递给'new CursorLoader()'的内容URI?我没有使用任何外部数据,例如设备联系人等.

请参阅下面的代码.我对如何为BASE_URI生成值感到困惑:

public class FavoritesFragment extends ListFragment implements
    LoaderManager.LoaderCallbacks<Cursor> {

SimpleCursorAdapter mAdapter;

static final String[] FAVORITES_SUMMARY_PROJECTION = new String[] {
        MyApplication.COLUMN_ID, MyApplication.COLUMN_ADDRESS,
        MyApplication.COLUMN_DISTANCE, };

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mAdapter = new SimpleCursorAdapter(getActivity(),
            R.layout.locations_list_row, null, new String[] {
                    MyApplication.COLUMN_ADDRESS,
                    MyApplication.COLUMN_DISTANCE }, new int[] {
                    R.id.address2, R.id.distance }, 0);
    setListAdapter(mAdapter);

    getLoaderManager().initLoader(0, null, this);
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    // Insert desired behavior here.
}

public …
Run Code Online (Sandbox Code Playgroud)

java android android-cursor android-loadermanager

3
推荐指数
1
解决办法
4914
查看次数

Android sqlite多线程

我正在编写一个Android应用程序sqlite.有许多活动和一项服务.我使用来自多个线程的数据库.它完美地Android 2.X运行,但是一旦我在它中运行Android 3.X它总是抛出这个错误,并且Force Close:

05-04 22:17:04.815: I/SqliteDatabaseCpp(8774): sqlite returned: error code = 5, msg = database is locked, db=/data/data/xxx/databases/im
05-04 22:17:04.815: E/SqliteDatabaseCpp(8774): sqlite3_open_v2("/data/data/xxx/databases/im", &handle, 6, NULL) failed
05-04 22:17:04.835: E/SQLiteDatabase(8774): Failed to open the database. closing it.
05-04 22:17:04.835: E/SQLiteDatabase(8774): android.database.sqlite.SQLiteDatabaseLockedException: database is locked
05-04 22:17:04.835: E/SQLiteDatabase(8774):     at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
05-04 22:17:04.835: E/SQLiteDatabase(8774):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983)
05-04 22:17:04.835: E/SQLiteDatabase(8774):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956)
05-04 22:17:04.835: E/SQLiteDatabase(8774):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021)
05-04 22:17:04.835: E/SQLiteDatabase(8774):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:790)
05-04 22:17:04.835: …
Run Code Online (Sandbox Code Playgroud)

sqlite multithreading android android-loadermanager

3
推荐指数
1
解决办法
2万
查看次数

除非我在loadInBackground中返回一个新对象,否则AsyncTaskLoader不会调用onLoadFinished

我有一个AsyncTaskLoader<List<String>>成员变量List<String>mAddresses.在loadInBackground,如果我创建一个新对象,填充它,并返回它; onLoadFinished按预期调用,所以我可以更新适配器,然后更新视图.

    public List<String> loadInBackground()
    {
        // ListView updates properly only if I do this (strange?)
        mAddresses = new ArrayList<String>();

        // ... fill mAddresses ...

        return mAddresses;
    }
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试使用相同的变量,即使它的值发生变化也会onLoadFinished被调用:

    public List<String> loadInBackground()
    {
        // ListView does not update with this!
        if(mAddresses == null)
        {
           mAddresses = new ArrayList<String>();
        }

        // ... fill mAddresses ...

        return mAddresses;
    }
Run Code Online (Sandbox Code Playgroud)

任何人都可以评论这个吗?我是否应该像这样创建一个新对象来返回?是否有任何标志我可以设置"对象已更改,所以即使它是同一个对象,请确保执行所有更新?

android asynctaskloader android-loadermanager android-loader

3
推荐指数
1
解决办法
2504
查看次数

光标未使用自定义适配器正确绑定文本

SimpleCursorAdapter为我扩展的自定义适配器ListFragment无法正确显示数据库中的项目.它不会在TextView中显示文本,我还需要对光标做什么才能显示正确的文本?

我以为我必须覆盖bindView但没有效果

设置适配器:

public void populateList(){

        String[] fields = new String[] {BowlersDB.NAME};
        Cursor c = getActivity().getContentResolver().query(BowlersDB.CONTENT_URI,
                new String[] {BowlersDB.ID,BowlersDB.NAME},null,null,BowlersDB.NAME + " COLLATE LOCALIZED ASC");

mAdapter = new CheckAdapter(getActivity(),R.layout.check_listview,c,fields,new int[] {R.id.nameCheckTV});


        setListAdapter(mAdapter);   

        getLoaderManager().initLoader(0,null,this);
    }
Run Code Online (Sandbox Code Playgroud)

适配器:

public class CheckAdapter extends SimpleCursorAdapter{

    Context context;
    Cursor c;

    public CheckAdapter(Context context, int layout, Cursor c,String[] from, int[] to) {
        super(context, layout, c, from, to);
        this.context = context;
        this.c = c;
        // TODO Auto-generated constructor stub
    }

    @Override
    public void …
Run Code Online (Sandbox Code Playgroud)

android android-listview android-cursor android-loadermanager android-cursoradapter

2
推荐指数
1
解决办法
1264
查看次数

Android - 尝试重新打开已经关闭的对象:使用loaderManager的SQLiteQuery

我对Android很新,我对过滤的listView和从横向模式更改为纵向模式或反之亦然的活动有一些问题.我有一个editText用于过滤"drinkSearch",只要我不改变视角(人像与风景),这个过滤就有效.这是我得到的错误:

java.lang.IllegalStateException:尝试重新打开已经关闭的对象:SQLiteQuery:SELECT _id,name FROM drinks

正如您在下面的代码中看到的,我使用了接口LoaderManager.LoaderCallbacks,这个概念对我来说有点新,我不确定哪里出了问题.我将非常感谢所有的帮助,在此先感谢!

public class Drinks_Fragment extends Fragment实现LoaderManager.LoaderCallbacks {

private static final int DRINKS_LIST_LOADER = 0x01;
private SimpleCursorAdapter adapter;
private ListView drinksList;
private String LOG;
private EditText drinkSearch;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.drinks_list, container, false);
    drinkSearch = (EditText)view.findViewById(R.id.drinkInputSearch);
    drinksList = (ListView) view.findViewById(R.id.drinksList);
    drinksList.setEmptyView(view.findViewById(R.id.empty_list_view));

    String[] from = {DrinksTable.COLUMN_NAME};
    int[] to = {R.id.drinkName};
    getLoaderManager().initLoader(DRINKS_LIST_LOADER, null, this);
    adapter = new SimpleCursorAdapter(getActivity().getApplicationContext(), R.layout.drinks_list_item,null, from, to, 0);
    drinksList.setAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)

在这部分中,我根据searchDrink editText中输入的字符串向contentProvider询问新的Cursor.(以下代码,直到"返回视图"正好在上面的部分下方,同样的onCreateView方法)

    drinkSearch.addTextChangedListener(new TextWatcher() { …
Run Code Online (Sandbox Code Playgroud)

android android-contentprovider android-listview android-loadermanager android-sqlite

2
推荐指数
1
解决办法
3986
查看次数

为什么加载器不能成为非静态内部类?

当我尝试使用非静态内部Loader类时,我收到以下运行时错误:

从onCreateLoader返回的对象不能是非静态内部成员类

这个限制有什么意义?

android android-loadermanager android-loader

2
推荐指数
1
解决办法
1025
查看次数