Android 异步执行在 onCreate 之后
Android Async Execution comes after onCreate
我真的是 android 应用程序创建的新手,我正在使用 Android studio 来处理我的项目。我正在从我的数据库中获取 json 结果并且获取的结果是我想要的,但我不知道如何让 asynctask 在 onCreate 之前完成。我的 ListView 是空的,但我通过调试器确认我的异步任务结果值存在。
更新:我跟踪错误到这里:
public void populatedata(){
/**get back result from pref**/
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
String result =pref.getString("result", "null");
try{
Log.d("ADebugTag", "Value: "+result);
JSONObject person = new JSONObject(result);
JSONArray jsonMainNode = person.getJSONArray("result");
final int n = jsonMainNode.length();
ListView lv= (ListView)findViewById(R.id.listView1);
String[] from = new String[] {"id", "time"};
int[] to = new int[] {android.R.id.text1};
List<Map<String,String>> classList = new ArrayList<Map<String,String>>();
// for(int i = 0; i< n; i++){
//HashMap<String, String> map = new HashMap<String, String>();
// JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
// String id = jsonChildNode.getString("id");
// String schedule = jsonChildNode.getString("schedule");
// String time = jsonChildNode.getString("time");
// String output = schedule + time;
// classList.add(createchild(id,output));
// Log.d("ADebugTag", "Value before loop: "+classList);
// }
// Log.d("ADebugTag", "Value after loop: "+classList);
Log.d("ADebugTag", "Hi, Im here5");
for(int i = 0; i < 10; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("id", "time" + i);
map.put("col_1", "col_1_item_" + i);
map.put("col_2", "col_2_item_" + i);
map.put("col_3", "col_3_item_" + i);
classList.add(map);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this,classList, android.R.layout.simple_list_item_1, from, to);
lv.setAdapter(simpleAdapter);
}
catch(JSONException e){
Toast.makeText(getApplicationContext(), "Error"+e.toString(), Toast.LENGTH_SHORT).show();
}
}
private HashMap<String, String>createchild(String id,String output){
HashMap<String,String> childNo = new HashMap<String,String>();
childNo.put(id,output);
Log.d("ADebugTag", "Hi, Im here4");
return childNo;
}
the // for loop is the one i wanna work it out, and my string result `is{"result":[{"id":"00000000001","schedule":"000001","time":"10:21:37"}]}`
updated: It's my mistake, I did not create a R.layout and textview for it, I learned to use custom adapter and create an external layout.
public class ViewClassActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_class);
/**prepare list**/
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
String id =pref.getString("userid", "null");
Log.d("ADebugTag", "Hi, Im here");
new fetchclass(this,id).execute(id);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void getdata(String result){
//save preferences
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString("result", result); // Saving result string
Log.d("ADebugTag", "Hi, Im here3");
// Save the changes in SharedPreferences
editor.apply(); // apply changes
populatedata();
Log.d("ADebugTag", "Hi, Im here6");
}
public void populatedata(){
/**get back result from pref**/
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
String result =pref.getString("result", "null");
Log.d("ADebugTag",result);
try{
Log.d("ADebugTag", "Value: "+result);
JSONObject person = new JSONObject(result);
JSONArray jsonMainNode = person.getJSONArray("result");
final int n = jsonMainNode.length();
ListView lv= (ListView)findViewById(R.id.listView1);
String[] from = new String[] {"id", "schedule"};
int[] to = new int[] {R.id.textView20,R.id.textView21};
//List<Map<String,String>> classList = new ArrayList<Map<String,String>>();
ArrayList<HashMap<String,String>> classList = new ArrayList<>();
for(int i = 0; i< n; i++){
HashMap<String, String> hashMap = new HashMap<>();
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String id = jsonChildNode.getString("id");
String schedule = jsonChildNode.getString("schedule");
String time = jsonChildNode.getString("time");
String output = schedule + time;
hashMap.put("id", id);
hashMap.put("schedule", output);
classList.add(hashMap);
//classList.add(createchild(id,output));
Log.d("ADebugTag", "Value before loop: "+classList);
}
CustomAdapter simpleAdapter = new CustomAdapter(this,classList, R.layout.list_view_item, from, to);
lv.setAdapter(simpleAdapter);
}
catch(JSONException e){
Toast.makeText(getApplicationContext(), "Error"+e.toString(), Toast.LENGTH_SHORT).show();
}
}
private HashMap<String, String>createchild(String id,String output){
HashMap<String,String> childNo = new HashMap<String,String>();
childNo.put(id,output);
Log.d("ADebugTag", "Hi, Im here4");
return childNo;
}
list_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/textView20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="@dimen/activity_horizontal_margin"
android:text="Demo1"
android:textColor="#000" />
<TextView
android:id="@+id/textView21"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="@dimen/activity_horizontal_margin"
android:text="Demo2"
android:textColor="#000"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/textView20"
android:layout_toEndOf="@+id/textView20" />
</RelativeLayout>
自定义适配器
public class CustomAdapter extends SimpleAdapter {
LayoutInflater inflater;
Context context;
ArrayList<HashMap<String, String>> arrayList;
public CustomAdapter(Context context, ArrayList<HashMap<String, String>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.context = context;
this.arrayList = data;
inflater.from(context);
}
}
使用此站点解决了我的问题,感谢大家的帮助:
您不能让异步任务在 onCreate 之前完成。这就是异步任务的全部要点——它并行执行。相反,您应该设置一个加载屏幕(即使只是像不确定的进度条一样简单的东西)向用户显示您正在等待数据,然后将数据加载到任务的 onPostExecute 列表中。
试试下面的代码:
public class ViewClassActivity extends AppCompatActivity{
List<Map<String,String>> classList = new ArrayList<Map<String,String>>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_class);
/**prepare list**/
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
String id =pref.getString("userid", "null");
ListView listView = (ListView) findViewById(R.id.listView1);
SimpleAdapter simpleAdapter = new SimpleAdapter(this,classList, android.R.layout.simple_list_item_1, new String[] {"result"}, new int[] {android.R.id.text1});
listView.setAdapter(simpleAdapter);
Log.d("ADebugTag", "Hi, Im here5");
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Log.d("ADebugTag", "Hi, Im here");
new fetchclass(this,id).execute(id);
}
private HashMap<String, String>createchild(String id,String output){
HashMap<String,String> childNo = new HashMap<String,String>();
childNo.put(id,output);
Log.d("ADebugTag", "Hi, Im here4");
return childNo;
}
public class fetchclass extends AsyncTask<String,String,String>{
ProgressDialog proDialog;
String userid;
public ViewClassActivity activity;
public fetchclass(ViewClassActivity a, String id) {
this.activity = a;
this.userid = id;
}
protected void onPreExecute(){
//pre-execute procedure
// Showing progress loading dialog
proDialog = new ProgressDialog(activity);
proDialog.setMessage("Loading...");
proDialog.setCancelable(false);
proDialog.show();
}
@Override
protected String doInBackground(String... arg0) {
try{
String id = arg0[0];
String link="http://www.commcreative.me/mnas/attendance.php";
String data = URLEncoder.encode("id", "UTF-8") + "=" + URLEncoder.encode(id, "UTF-8");
URL url = new URL(link);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
sb.append(line);
break;
}
try{
Log.d("ADebugTag", "Value: "+sb.toString(););
JSONObject person = new JSONObject(sb.toString(););
JSONArray jsonMainNode = person.getJSONArray("result");
final int n = jsonMainNode.length();
for(int i = 0; i<n;i++){
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String id = jsonChildNode.getString("id");
String schedule = jsonChildNode.getString("schedule");
String time = jsonChildNode.getString("time");
String output = schedule + time;
classList.add(createchild(id,output));
Log.d("ADebugTag", "Value: "+classList);
}
simpleAdapter .notifyDataSetChange();
}
catch(JSONException e){
Toast.makeText(getApplicationContext(), "Error"+e.toString(), Toast.LENGTH_SHORT).show();
}
return sb.toString();
}
catch(Exception e){
return new String("Exception: " + e.getMessage());
}
}
@Override
protected void onPostExecute(String result){
// Dismiss the progress dialog
if (proDialog.isShowing())
proDialog.dismiss();
//dismiss end
// Log.d("ADebugTag", "Hi, Im here2");
// activity.getdata(result);
}
}
private HashMap<String, String>createchild(String id,String output){
HashMap<String,String> childNo = new HashMap<String,String>();
childNo.put(id,output);
Log.d("ADebugTag", "Hi, Im here4");
return childNo;
}
}
我真的是 android 应用程序创建的新手,我正在使用 Android studio 来处理我的项目。我正在从我的数据库中获取 json 结果并且获取的结果是我想要的,但我不知道如何让 asynctask 在 onCreate 之前完成。我的 ListView 是空的,但我通过调试器确认我的异步任务结果值存在。
更新:我跟踪错误到这里:
public void populatedata(){
/**get back result from pref**/
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
String result =pref.getString("result", "null");
try{
Log.d("ADebugTag", "Value: "+result);
JSONObject person = new JSONObject(result);
JSONArray jsonMainNode = person.getJSONArray("result");
final int n = jsonMainNode.length();
ListView lv= (ListView)findViewById(R.id.listView1);
String[] from = new String[] {"id", "time"};
int[] to = new int[] {android.R.id.text1};
List<Map<String,String>> classList = new ArrayList<Map<String,String>>();
// for(int i = 0; i< n; i++){
//HashMap<String, String> map = new HashMap<String, String>();
// JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
// String id = jsonChildNode.getString("id");
// String schedule = jsonChildNode.getString("schedule");
// String time = jsonChildNode.getString("time");
// String output = schedule + time;
// classList.add(createchild(id,output));
// Log.d("ADebugTag", "Value before loop: "+classList);
// }
// Log.d("ADebugTag", "Value after loop: "+classList);
Log.d("ADebugTag", "Hi, Im here5");
for(int i = 0; i < 10; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("id", "time" + i);
map.put("col_1", "col_1_item_" + i);
map.put("col_2", "col_2_item_" + i);
map.put("col_3", "col_3_item_" + i);
classList.add(map);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this,classList, android.R.layout.simple_list_item_1, from, to);
lv.setAdapter(simpleAdapter);
}
catch(JSONException e){
Toast.makeText(getApplicationContext(), "Error"+e.toString(), Toast.LENGTH_SHORT).show();
}
}
private HashMap<String, String>createchild(String id,String output){
HashMap<String,String> childNo = new HashMap<String,String>();
childNo.put(id,output);
Log.d("ADebugTag", "Hi, Im here4");
return childNo;
}
the // for loop is the one i wanna work it out, and my string result `is{"result":[{"id":"00000000001","schedule":"000001","time":"10:21:37"}]}`
updated: It's my mistake, I did not create a R.layout and textview for it, I learned to use custom adapter and create an external layout.
public class ViewClassActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_class);
/**prepare list**/
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
String id =pref.getString("userid", "null");
Log.d("ADebugTag", "Hi, Im here");
new fetchclass(this,id).execute(id);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void getdata(String result){
//save preferences
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString("result", result); // Saving result string
Log.d("ADebugTag", "Hi, Im here3");
// Save the changes in SharedPreferences
editor.apply(); // apply changes
populatedata();
Log.d("ADebugTag", "Hi, Im here6");
}
public void populatedata(){
/**get back result from pref**/
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
String result =pref.getString("result", "null");
Log.d("ADebugTag",result);
try{
Log.d("ADebugTag", "Value: "+result);
JSONObject person = new JSONObject(result);
JSONArray jsonMainNode = person.getJSONArray("result");
final int n = jsonMainNode.length();
ListView lv= (ListView)findViewById(R.id.listView1);
String[] from = new String[] {"id", "schedule"};
int[] to = new int[] {R.id.textView20,R.id.textView21};
//List<Map<String,String>> classList = new ArrayList<Map<String,String>>();
ArrayList<HashMap<String,String>> classList = new ArrayList<>();
for(int i = 0; i< n; i++){
HashMap<String, String> hashMap = new HashMap<>();
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String id = jsonChildNode.getString("id");
String schedule = jsonChildNode.getString("schedule");
String time = jsonChildNode.getString("time");
String output = schedule + time;
hashMap.put("id", id);
hashMap.put("schedule", output);
classList.add(hashMap);
//classList.add(createchild(id,output));
Log.d("ADebugTag", "Value before loop: "+classList);
}
CustomAdapter simpleAdapter = new CustomAdapter(this,classList, R.layout.list_view_item, from, to);
lv.setAdapter(simpleAdapter);
}
catch(JSONException e){
Toast.makeText(getApplicationContext(), "Error"+e.toString(), Toast.LENGTH_SHORT).show();
}
}
private HashMap<String, String>createchild(String id,String output){
HashMap<String,String> childNo = new HashMap<String,String>();
childNo.put(id,output);
Log.d("ADebugTag", "Hi, Im here4");
return childNo;
}
list_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/textView20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="@dimen/activity_horizontal_margin"
android:text="Demo1"
android:textColor="#000" />
<TextView
android:id="@+id/textView21"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="@dimen/activity_horizontal_margin"
android:text="Demo2"
android:textColor="#000"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/textView20"
android:layout_toEndOf="@+id/textView20" />
</RelativeLayout>
自定义适配器
public class CustomAdapter extends SimpleAdapter {
LayoutInflater inflater;
Context context;
ArrayList<HashMap<String, String>> arrayList;
public CustomAdapter(Context context, ArrayList<HashMap<String, String>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.context = context;
this.arrayList = data;
inflater.from(context);
}
}
使用此站点解决了我的问题,感谢大家的帮助:
您不能让异步任务在 onCreate 之前完成。这就是异步任务的全部要点——它并行执行。相反,您应该设置一个加载屏幕(即使只是像不确定的进度条一样简单的东西)向用户显示您正在等待数据,然后将数据加载到任务的 onPostExecute 列表中。
试试下面的代码:
public class ViewClassActivity extends AppCompatActivity{
List<Map<String,String>> classList = new ArrayList<Map<String,String>>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_class);
/**prepare list**/
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
String id =pref.getString("userid", "null");
ListView listView = (ListView) findViewById(R.id.listView1);
SimpleAdapter simpleAdapter = new SimpleAdapter(this,classList, android.R.layout.simple_list_item_1, new String[] {"result"}, new int[] {android.R.id.text1});
listView.setAdapter(simpleAdapter);
Log.d("ADebugTag", "Hi, Im here5");
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Log.d("ADebugTag", "Hi, Im here");
new fetchclass(this,id).execute(id);
}
private HashMap<String, String>createchild(String id,String output){
HashMap<String,String> childNo = new HashMap<String,String>();
childNo.put(id,output);
Log.d("ADebugTag", "Hi, Im here4");
return childNo;
}
public class fetchclass extends AsyncTask<String,String,String>{
ProgressDialog proDialog;
String userid;
public ViewClassActivity activity;
public fetchclass(ViewClassActivity a, String id) {
this.activity = a;
this.userid = id;
}
protected void onPreExecute(){
//pre-execute procedure
// Showing progress loading dialog
proDialog = new ProgressDialog(activity);
proDialog.setMessage("Loading...");
proDialog.setCancelable(false);
proDialog.show();
}
@Override
protected String doInBackground(String... arg0) {
try{
String id = arg0[0];
String link="http://www.commcreative.me/mnas/attendance.php";
String data = URLEncoder.encode("id", "UTF-8") + "=" + URLEncoder.encode(id, "UTF-8");
URL url = new URL(link);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
sb.append(line);
break;
}
try{
Log.d("ADebugTag", "Value: "+sb.toString(););
JSONObject person = new JSONObject(sb.toString(););
JSONArray jsonMainNode = person.getJSONArray("result");
final int n = jsonMainNode.length();
for(int i = 0; i<n;i++){
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String id = jsonChildNode.getString("id");
String schedule = jsonChildNode.getString("schedule");
String time = jsonChildNode.getString("time");
String output = schedule + time;
classList.add(createchild(id,output));
Log.d("ADebugTag", "Value: "+classList);
}
simpleAdapter .notifyDataSetChange();
}
catch(JSONException e){
Toast.makeText(getApplicationContext(), "Error"+e.toString(), Toast.LENGTH_SHORT).show();
}
return sb.toString();
}
catch(Exception e){
return new String("Exception: " + e.getMessage());
}
}
@Override
protected void onPostExecute(String result){
// Dismiss the progress dialog
if (proDialog.isShowing())
proDialog.dismiss();
//dismiss end
// Log.d("ADebugTag", "Hi, Im here2");
// activity.getdata(result);
}
}
private HashMap<String, String>createchild(String id,String output){
HashMap<String,String> childNo = new HashMap<String,String>();
childNo.put(id,output);
Log.d("ADebugTag", "Hi, Im here4");
return childNo;
}
}