【问题标题】:Android Async task get json string from webAndroid异步任务从网络获取json字符串
【发布时间】:2014-03-06 14:33:06
【问题描述】:

我的班级从网络读取一个 json 字符串,并用收集到的字符串填充一个哈希图。 我正在使用 AsyncTask 通过进度对话框读取数据,让用户知道该设计“正在工作”。 这是我的课:

class ArmoryAsyncProgress extends AsyncTask<String, Void, Void> {

    private Context         mContext;
    private ProgressDialog  mProgressDialog;
    private String tempRes;

    public ArmoryAsyncProgress(Context mContext)
    {
        this.mContext = mContext;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = ProgressDialog.show(mContext, "Carica!", "Gira!");
    }

    @SuppressLint("NewApi")
    @Override
    protected String doInBackground(String... sUrl) {
        try {
            URL json = new URL(Utility.BASE_URL + "api.php?action=armory&guid="+pGuid);
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            json.openStream()));
            String input;
            while((input = in.readLine()) != null)
                Result += input;

            json = new URL(Utility.BASE_URL + "api.php?action=armory_stats&guid="+pGuid);
            in = new BufferedReader(
                    new InputStreamReader(
                            json.openStream()));
            input = "";
            String ret = "";
            while((input = in.readLine()) != null)
                ret += input;

            tempRes = Result + "Ø" + ret;
            String debug = tempRes;
        }
        catch(MalformedURLException e){
            e.printStackTrace();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }

        ActivityArmory.result = tempRes;
        return null;
    }

    protected void onPostExecute(String result) {

        /*********************************************************************************/
        try
        {
            String ret;
            while(result == null)
                Thread.sleep(500);
            String[] temp = result.split("Ø");
            pJSON = temp[0];
            ret = temp[1];

            JSONObject pl = new JSONObject(ret);
            stats.put("Level", pl.getString("level"));
            stats.put("Classe", pl.getString("class"));
            stats.put("Name", pl.getString("pname"));
            stats.put("Race", pl.getString("race"));

            stats.put("health", pl.getString("health"));
            stats.put("power", pl.getString("power1"));
            stats.put("gname", pl.getString("gname"));
            stats.put("pnote", pl.getString("pnote"));
            stats.put("offnote", pl.getString("offnote"));
            stats.put("rname", pl.getString("rname"));

            JSONArray jObject = new JSONArray(pJSON);

            for (int i = 0; i < jObject.length(); i++) {
                JSONObject item = jObject.getJSONObject(i);
                ArmoryElement i1 = new ArmoryElement(
                        "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg",
                        item.getInt("itemID"), item.getInt("quality"));

                el.put(item.getString("itemType"), i1);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    /****************************************************************/

        mProgressDialog.dismiss();
    }
}

这是对类的调用:

new ArmoryAsyncProgress().execute(pGuid+"");

在“执行”方法调用之后,我调用了另一个函数,用于格式化和显示从 Web 获取的数据。 我的问题是没有显示在 Async 类中声明的 progressDialog 并且在执行完成之前调用了执行后调用的函数(使用一些日志我发现第二个函数中的日志在 doInBackground 完成之前显示)

我也试过 .get 方法,它会冻结主线程并阻止函数被调用,但我无法显示进度对话框。

提前致谢

【问题讨论】:

  • 异步任务异步工作是正常的。只有当他进入 onPostExecute 时才能确定异步任务终止。
  • 我该怎么做才能防止代码被执行?
  • 我发布了真正的问题,你应该传递已经解析的对象并且只做 gui 的东西。但检查我的答案,问题是你返回 null。

标签: android multithreading asynchronous


【解决方案1】:

PostExecute() 不能执行大操作,使用doInBackground 中的json 解析等繁重操作。要显示 UI,即在 textview 或 listview 中显示,请使用 PostExecute()

【讨论】:

    【解决方案2】:

    执行后调用的函数在执行完成之前被调用

    这是正常的,因为AsyncTasks 是异步的,这意味着它们将在后台运行并允许您的其他代码继续运行。为了解决这个问题,

    1. 如果任务是Activity的内部类,可以调用 onPostExecute()

    2. 完成后要运行的函数
    3. 如果不是,您可以使用interface 提供回调 完成后发送至ActivitySee this answer for an example on interface

    为什么ProgressDialog 没有显示,我不太确定,但您可以先从onPostExecute() 中删除Thread.sleep(),因为这会使您的主线程休眠。我看到的唯一需要在onPostExecute() 中的是mProgressDialog.dismiss()。其余的可以在doInBackground()完成。

    另外,你使用.get() 是对的,它会冻结你的UI Thread

    【讨论】:

      【解决方案3】:

      你必须改变 doInBackground 的返回值,因为这个值是在 onPostExecute 中使用的

      【讨论】:

        【解决方案4】:

        不好的地方是:

            protected void onPostExecute(String result) {
        
            /*********************************************************************************/
            try
            {
                String ret;
                while(result == null)
                    Thread.sleep(500);
        

        因为它在UI线程中运行,会与严格模式冲突。

            protected void onPostExecute(String result) {
        if(result!=null){
            /*********************************************************************************/
            try
            {
                String ret;
        
                String[] temp = result.split("Ø");
                pJSON = temp[0];
                ret = temp[1];
        
                JSONObject pl = new JSONObject(ret);
                stats.put("Level", pl.getString("level"));
                stats.put("Classe", pl.getString("class"));
                stats.put("Name", pl.getString("pname"));
                stats.put("Race", pl.getString("race"));
        
                stats.put("health", pl.getString("health"));
                stats.put("power", pl.getString("power1"));
                stats.put("gname", pl.getString("gname"));
                stats.put("pnote", pl.getString("pnote"));
                stats.put("offnote", pl.getString("offnote"));
                stats.put("rname", pl.getString("rname"));
        
                JSONArray jObject = new JSONArray(pJSON);
        
                for (int i = 0; i < jObject.length(); i++) {
                    JSONObject item = jObject.getJSONObject(i);
                    ArmoryElement i1 = new ArmoryElement(
                            "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg",
                            item.getInt("itemID"), item.getInt("quality"));
        
                    el.put(item.getString("itemType"), i1);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        /****************************************************************/
        }
            mProgressDialog.dismiss();
        }
        

        更糟糕的是:

         return null;
        

        在你的 doInBackground 方法中

        但是,这应该可以:

        class ArmoryAsyncProgress extends AsyncTask<String, Void, Void> {
        
            private Context         mContext;
            private ProgressDialog  mProgressDialog;
            private String tempRes;
        
            public ArmoryAsyncProgress(Context mContext)
            {
                this.mContext = mContext;
            }
        
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                mProgressDialog = ProgressDialog.show(mContext, "Carica!", "Gira!");
            }
        
            @SuppressLint("NewApi")
            @Override
            protected String doInBackground(String... sUrl) {
                try {
                    URL json = new URL(Utility.BASE_URL + "api.php?action=armory&guid="+pGuid);
                    BufferedReader in = new BufferedReader(
                            new InputStreamReader(
                                    json.openStream()));
                    String input;
                    while((input = in.readLine()) != null){
                        Result += input;
                    }
                    json = new URL(Utility.BASE_URL + "api.php?action=armory_stats&guid="+pGuid);
                    in = new BufferedReader(
                            new InputStreamReader(
                                    json.openStream()));
                    input = "";
                    String ret = "";
                    while((input = in.readLine()) != null){
                        ret += input;
                    }
                    tempRes = Result + "Ø" + ret;
                    String debug = tempRes;
                }
                catch(MalformedURLException e){
                    e.printStackTrace();
                }
                catch (IOException ex) {
                    ex.printStackTrace();
                }
        
                ActivityArmory.result = tempRes;
                return tempRes;
            }
        
            protected void onPostExecute(String result) {
                if(result!=null)
                /*********************************************************************************/
                try
                {
                    String ret;
                    String[] temp = result.split("Ø");
                    pJSON = temp[0];
                    ret = temp[1];
        
                    JSONObject pl = new JSONObject(ret);
                    stats.put("Level", pl.getString("level"));
                    stats.put("Classe", pl.getString("class"));
                    stats.put("Name", pl.getString("pname"));
                    stats.put("Race", pl.getString("race"));
        
                    stats.put("health", pl.getString("health"));
                    stats.put("power", pl.getString("power1"));
                    stats.put("gname", pl.getString("gname"));
                    stats.put("pnote", pl.getString("pnote"));
                    stats.put("offnote", pl.getString("offnote"));
                    stats.put("rname", pl.getString("rname"));
        
                    JSONArray jObject = new JSONArray(pJSON);
        
                    for (int i = 0; i < jObject.length(); i++) {
                        JSONObject item = jObject.getJSONObject(i);
                        ArmoryElement i1 = new ArmoryElement(
                                "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg",
                                item.getInt("itemID"), item.getInt("quality"));
        
                        el.put(item.getString("itemType"), i1);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            /****************************************************************/
            }
                mProgressDialog.dismiss();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-09-11
          • 2012-07-21
          • 2015-09-20
          • 2016-03-12
          • 1970-01-01
          • 2015-12-04
          • 1970-01-01
          相关资源
          最近更新 更多