【问题标题】:Android Async Execution comes after onCreateAndroid 异步执行在 onCreate 之后
【发布时间】:2016-07-07 15:18:22
【问题描述】:

我对创建 Android 应用程序非常陌生,我正在使用 Android Studio 来处理我的项目。我正在从我的数据库中获取 json 结果,并且获取的结果是我想要的,但我不知道如何让 asynctask 在 onCreate 之前完成。我的 ListView 是空的,但我通过调试器确认我的 asynctask 结果值存在。

更新:我跟踪错误到这里:

  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);
    }



}

在使用这个网站时发现了我的问题,感谢大家的帮助:

custom-listview

【问题讨论】:

  • 因为当执行异步时,后台线程启动(使用 onPost() 发布结果)并且程序移至下一行......而且我可以看到您的列表视图甚至在后台任务之前填充了适配器已完成...我建议的一个解决方案是在您的任务完成后设置适配器,即在您的 getdata(String result) 中的 populatedata(); 之后调用 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); 并检查结果
  • @Mohit 你的推荐作品!我的调试器现在告诉我代码运行我想要的序列!但我仍然面临空列表视图!可能是生成hasmap的原因吗?我获得的字符串值为 {"result":[{"id":"00000000001","schedule":"000001","time":"10:21:37"}]}但是在 hasmap 之后它是 [{00000000001=00000110:21:37}] 并且顺便说一下在下面发布您的答案,以便我可以将其标记为勾号,尽管我的列表视图仍然存在,但您解决了我最基本的问题空白
  • 第一:请更新代码以便分析...... 第二:是,你是对的,每次你在循环中调用createchild()时,你都在初始化hashmap,你会得到新的空hashmap..只需声明全局hashmap变量并初始化一次(比如在onCreate()或某个地方但不在循环中)并在方法中调用它......希望它有帮助
  • 但我认为我的 hasmap 方法不在循环中?还是您的意思是这部分?String time = jsonChildNode.getString("time"); String output = schedule + time; classList.add(createchild(id,output)); Log.d("ADebugTag", "Value: "+classList); }createchild(id,output)); 带出循环?但是,怎么做?
  • 只需从 createchild() 中删除 HashMap&lt;String,String&gt; childNo = new HashMap&lt;String,String&gt;(); 并将其放在班级顶部,即低于 List&lt;Map&lt;String,String&gt;&gt; classList = new ArrayList&lt;Map&lt;String,String&gt;&gt;();

标签: android listview android-asynctask simpleadapter


【解决方案1】:

您不能让异步任务在 onCreate 之前完成。这就是异步任务的全部意义——它并行执行。相反,您应该设置一个加载屏幕(甚至只是像不确定的进度条这样简单的东西)来向用户显示您正在等待数据,然后将数据加载到任务的 onPostExecute 列表中。

【讨论】:

  • 如果您使用事件总线来处理异步任务,这将使您的生活更加轻松。 simonvt.net/2014/04/17/asynctask-is-bad-and-you-should-feel-bad
  • 不要将事件总线用于异步任务。这只会带来可怕的意大利面条代码。如果您需要使用事件总线,则意味着您已经完全设计了您的代码。
  • 为什么事件总线是一件坏事?
  • 因为它隐藏了应用程序的实际流程,使得调试更加困难。在没有实际运行程序的情况下,几乎不可能弄清楚谁真正响应了事件。它基本上是一个巨大的 goto - 自 60 年代以来我们一直在说 goto 很糟糕。
  • 所以只有进度对话框不行吗?
【解决方案2】:

试试下面的代码:

 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;

}



}

【讨论】:

  • fetchdata 类中存在很多错误 例如:'code'Log.d("ADebugTag", "Value: "+sb.toString();); JSONObject person = new JSONObject(sb.toString(););'code' the ;意外令牌,并且无法解析 simpleadapter 方法。抱歉,我真的不知道如何处理 simpleadapter 这个东西。
  • 使用这个链接一定能解决你的问题。learn2crack.com/2013/10/…
  • 它不教数组或列表视图,这是我没有问题的非循环方法
猜你喜欢
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多