I want to make an app lister application which fetches the application list via the packagemanager through an AsyncTask<Void, Void, List<PackageSummary>>
nested in a singleton class. However, if and only if I implement the async task, the RecyclerView will not populate on the first OnCreate.
I am sure I am doing a silly mistake and/or do not understand AsyncTask and RecyclerView well enough, but for the love of me I cannot find the root of the issue.
In my toy app repository I have prepared two, relatively cleaner branches for illustration purposes:
- One in which the packages are fetched in the main thread, and the recyclerview populates on first Oncreate (git_UI_thread).
- One in which an
AsyncTask<Void, Void, List<PackageSummary>>
class is called. The application persistence is not set yet (on purpose), and theRecyclerView
will only populate after the application is rotated (git_background_thread).
For those who are not inclined to click on the bitbucket link above, the code snippet of the inside of my AsyncTask
looks like this:
@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;
}
And this is my Main activity 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);
}
And this is how the singleton is fetched:
static SingletonPackageSummarySupplier instance;
public static SingletonPackageSummarySupplier getInstance(Context context) {
if (instance == null) {
instance = new SingletonPackageSummarySupplier(context);
} else{
instance.updateInstance(context);
}
return instance;
}
P.S.: I think (but not sure) the singleton pattern is justified in order to diminish the changes of memory leaks.
P.S.2: I have read a couple questions about this, but none had an accepted / working solution.