java - doInBackground 不在 Activity onCreate 内运行
问题描述
我所拥有的: 我有一个SearchActivity,它从一个片段(单击按钮后)接收一个 ArrayList (NameDesSearch)并更新一个简单的listview。当我单击列表视图项时,单击的列表项的相应对象(orgDesObj)会出现一个新视图。此功能运行良好。
当前接收列表(NameDesSearch)由名称和描述组成。都是字符串。
但是,我只想显示列表名称。因此我尝试创建一个函数(titlefunc())。这里创建了一个新的 ArrayList ( NameDesTitles ) 以仅添加相关名称。
问题: 但是,在我调用 titlefunc() 时,Do In 后台功能似乎无法正常工作。
尝试: 我放了几个Log来捕捉点。我也在单击项目的列表视图中使用相同的函数( getLocDesOb() )。令人惊讶的是它有效,甚至 doInBackground 函数也有效。但是当搜索活动创建并调用 titlefunc()时,doInBackground中的搜索列表 ( finalODescriptionArrayList ) 为空()。形成日志,我收到finalODescriptionArrayList的内容为 [],大小为 0。但是,当我单击列表视图项时finalODescriptionArrayList更新。
我什至也尝试过移出NameDesSearch = getIntent().getStringArrayListExtra("searched");
该功能。
似乎我的 doInBackground 方法仅在单击列表项而不是创建活动时调用。其他所有功能都运行良好。我不确定为什么我的titlefunc()被调用,为什么finalODescriptionArrayList没有更新。
我将不胜感激有关此的任何建议。谢谢 !
我的代码:为了清楚起见,我删除了日志。
public class SearchActivity extends AppCompatActivity {
ListView searchedListView;
String SearchedWord;
private ArrayAdapter<String> orgAdapter;
ArrayList<String> NameDesSearch = new ArrayList<String>();
ArrayList<String> NameDesTitles = new ArrayList<String>();
private OService OService;
ArrayList<ODescription> finalODescriptionArrayList = new ArrayList<ODescription>();
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
searchedListView = (ListView) findViewById(R.id.searched_list_view);
new GetCourse().execute();
titlefunc();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, NameDesTitles);
searchedListView.setAdapter(arrayAdapter);
searchedListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String selectedItemText = parent.getItemAtPosition(position).toString();
ODescription orgDesObj = getLocDesOb(selectedItemText);
if (orgDesObj != null) {
Intent intent = new Intent(SearchActivity.this, View.class);
intent.putExtra("sOb", orgDesObj);
startActivity(intent);
}
}
});
}
@SuppressLint("StaticFieldLeak")
private class GetCourse extends AsyncTask<Void, Void, Void> {
@TargetApi(Build.VERSION_CODES.N)
@Override
protected Void doInBackground(Void... voids) {
try {
finalODescriptionArrayList = JsontoObject.jsonToObjectData(getResources().openRawResource(R.raw.newdb));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
public ODescription getLocDesOb(String selectedItemText) {
if (finalODescriptionArrayList == null) {
return null;
}
for (ODescription locDescObj : finalODescriptionArrayList) {
if (locDescObj.getName().equals(selectedItemText) || locDescObj.getDescription().equals(selectedItemText)) {
return locDescObj;
}
}
return null;
}
public void titlefunc() {
NameDesSearch = getIntent().getStringArrayListExtra("searched");
for (String searchNameDes : NameDesSearch) {
ODescription orgDesObj2 = getLocDesOb(searchNameDes);
if (orgDesObj2 != null) {
NameDesTitles.add(orgDesObj2.getName());
}
}
}
}
使用onPostExecute 更新 AsyncTask下方答案后的尝试。然后因为它需要一点时间,所以添加了一个进度条onPreExecute。删除了 oncreate 方法中的titlefunc()。
这种方法现在有效。但是,有时也存在同样的问题。到适配器的 Arraylist 为空,因此 listview 为空。似乎仍然需要很多时间来完成后台任务。
更新了 AsyncTask
@SuppressLint("StaticFieldLeak")
private class GetCourse extends AsyncTask<Void, Void, Void> {
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(SearchActivity.this);
progressDialog.setMessage("Searching");
progressDialog.setCancelable(false);
progressDialog.show();
}
@TargetApi(Build.VERSION_CODES.N)
@Override
protected Void doInBackground(Void... voids) {
try {
finalODescriptionArrayList = JsontoObject.jsonToObjectData(getResources().openRawResource(R.raw.newdb));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
titlefunc();
arrayAdapter.notifyDataSetChanged();
if (progressDialog.isShowing())
progressDialog.dismiss();
}
}
修改 titlefunc() - 删除重复项
Set<String > set = new HashSet<>( NameDesTitles);
NameDesTitles.clear();
NameDesTitles.addAll(set);
解决方案
您AsyncTask
在后台异步运行。当您打电话时(很可能)它不会完成titleFunc()
(这就是您所看到的)。
您可以通过多种方式解决此问题。一种方法是在AsyncTask
完成后更新适配器的内容。您可以在后台处理完成时调用的其中onPostExecute()
执行此操作。AsyncTask
在该方法中,您可以运行您的titleFunc()
或类似的东西来过滤您想要显示的结果。然后,您需要通过调用来告诉您Adapter
更新视图。notifyDatasetChanged()
Adapter
推荐阅读
- mongodb - 数组中的MongoDB聚合匹配值
- amazon-web-services - DynamoDB 可扩展性:如何设计分区键与索引
- arrays - 将 MS Word 存储表中的行或列转换为 MS Word 文档中可搜索的文本数组
- python - 在终端上烧瓶正确的变量值,但在 HTML 模板中没有
- java - java.lang.NoSuchMethodError:Lcom/google/android/gms/common/zzc 类中没有静态方法 zza(Landroid/content/Context;)V;或其超类
- android - 如何在 Room 数据库中进行搜索?
- excel - VBA:从表复制并粘贴以创建列表
- python - 在没有多线程的情况下一次运行多个命令的方法?
- c - 如何使用 GLEW 进行自动 OpenGL 错误检查?
- javascript - Ramda:如果属性存在,使用它,如果不存在,检查另一个属性是否存在并使用它