Android AsyncTask RecyclerView不会填充

时间:2018-03-21 09:25:29

标签: java android android-recyclerview android-asynctask recycler-adapter

我想创建一个app lister应用程序,它通过packagemanager通过嵌套在单例类中的AsyncTask<Void, Void, List<PackageSummary>>获取应用程序列表。但是,当且仅当我实现异步任务时,RecyclerView才会填充第一个OnCreate。

我确信我犯了一个愚蠢的错误和/或不太了解AsyncTask和RecyclerView,但为了爱我,我找不到问题的根源。

In my toy app repository为了说明目的,我准备了两个相对更清晰的分支:

  • 在主线程中获取包,并在第一个Oncreate( git_UI_thread )上填充recyclerview。
  • 调用AsyncTask<Void, Void, List<PackageSummary>>类的一个。应用程序持久性尚未设置(故意),RecyclerView仅在应用程序轮换后填充( git_background_thread )。

对于那些不想点击上面的bitbucket链接的人,我AsyncTask内部的代码片段如下所示:

    @Override
    protected void onPostExecute(List<SingletonPackageSummarySupplier.PackageSummary> packageSummaries) {
        super.onPostExecute(packageSummaries);
        isQueryingInProgress = false;
        packageSummaryList = packageSummaries;
    }

    @Override
    protected List<SingletonPackageSummarySupplier.PackageSummary> doInBackground(Void... voids) {

        List<PackageSummary> installedPackages = new ArrayList<>();

        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

        List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentActivities(intent, 0);

        for (ResolveInfo resolveInfo : resolveInfoList) {

            ActivityInfo activityInfo = resolveInfo.activityInfo;

            installedPackages.add(new PackageSummary(resolveInfo.activityInfo));
        }

        return installedPackages;
    }

这是我的主要活动OnCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    psList = SingletonPackageSummarySupplier.getInstance(context).getPackageSummaryListReadOnly();
    setContentView(R.layout.activity_main);

    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

    recyclerViewLayoutManager = new LinearLayoutManager(context);

    recyclerView.setLayoutManager(recyclerViewLayoutManager);


    adapter = new AdapterApplist(context, psList);

    recyclerView.setAdapter(adapter);
}

这就是获取单身人士的方式:

static SingletonPackageSummarySupplier instance;
public static SingletonPackageSummarySupplier getInstance(Context context) {
    if (instance == null) {
        instance = new SingletonPackageSummarySupplier(context);
    } else{
        instance.updateInstance(context);
    }
    return instance;
}

P.S。:我认为(但不确定)单身模式是合理的,以减少内存泄漏的变化。

P.S.2:我已经阅读了几个关于此的问题,但没有人有一个接受/工作的解决方案。

3 个答案:

答案 0 :(得分:0)

只需在adapter.notifyDataSetChanged();

postexecute方法中添加AsyncTask即可

答案 1 :(得分:0)

有两个步骤:将数据更新到AdapterApplist并通知它。因此,您应该创建一个新方法,如:

public void setData(List<SingletonPackageSummarySupplier.PackageSummary> list)         
{ //reset your data ere
}

在AdapterApplist类中。然后,更新您的帖子:

@Override
    protected void onPostExecute(List<SingletonPackageSummarySupplier.PackageSummary> packageSummaries) {
        super.onPostExecute(packageSummaries);
        isQueryingInProgress = false;
        packageSummaryList = packageSummaries;
        adapter.setData(packageSummaryList);
        adapter.notifyDataSetChanged();
    }

答案 2 :(得分:0)

要么我无法实现观察者模式(请注意,asynctask是在与recyclelerview和activity分开的单例类中),或者在这种情况下它不能正常工作。

无论如何,我最终用相对较新的lifecycle-aware components来修复问题:MutableLiveData,LiveData和AndroidViewModel(而不是viewmodel,它不会将上下文作为构造函数参数)。它简单而优雅。

关键部分是活动:

    PackageSummarySupplier model = ViewModelProviders.of(this).get(PackageSummarySupplier.class);
    model.getPackageSummaryList().observe(this, packageSummaryList -> {
        adapter = new AdapterApplist(context, packageSummaryList);

        recyclerView.setAdapter(adapter);
    });