【问题标题】:Using AsyncTask with passing a value使用 AsyncTask 并传递一个值
【发布时间】:2016-05-14 13:57:10
【问题描述】:

我一直在努力,但我已经到了不知道该怎么做的地步。我想做的是使用一个类下载文件并将其解析为字符串,然后将该字符串发送到另一个类以解析出 JSON 内容。所有部件都可以自己正常工作,我已经分别测试了所有部件。我只是不知道如何将值发送到 Json 解析器以开始解析。

这是我的文件下载器类。

  public class JsonFileDownloader extends AsyncTask<String, Void, String> {
  //used to access the website
  String username = "admin";
  String password = "admin";
  public String ret = "";



  @Override
  protected String doInBackground(String... params) {
      Log.d("Params ", params[0].toString());
      readFromFile(params[0]);
      return ret;
  }

  private String readFromFile(String myWebpage) {

      HttpURLConnection urlConnection = null;

      try {
          //Get the url connection
          URL url = new URL(myWebpage);
          Authenticator.setDefault(new Authenticator() {
              @Override
             protected PasswordAuthentication getPasswordAuthentication()   {
                  return new PasswordAuthentication(username,   password.toCharArray());
            }
          });
          urlConnection = (HttpURLConnection) url.openConnection();

          InputStream inputStream = urlConnection.getInputStream();


          if (inputStream != null) {
              ret = streamToString(inputStream);
              inputStream.close();
              Log.d("Final String", ret);
          }

      } catch (FileNotFoundException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      } finally {
          if (urlConnection != null) {
              urlConnection.disconnect();
          }
          return ret;

      }
  }
  public static String streamToString(InputStream is) throws IOException   {

      StringBuilder sb = new StringBuilder();
      BufferedReader rd = new BufferedReader(new InputStreamReader(is));
      String line;
        while ((line = rd.readLine()) != null) {
          sb.append(line);
      }
       return sb.toString();
   }

  public String getJsonData()
  {
      return ret;
   }

}

这很好用,我一遍又一遍地测试它,没有错误。 接下来是Json解析器,就是这样的。

public class JSONParser {

JSONObject jsonResponse;
String jsonData;

//Consturctor
public JSONParser()
{
    //this.jsonData = jsonData;
    // this.OutputData = outPutData;
}

public void parsesData(String promo,
                       ArrayList<String> pictureHTTP,
                       ArrayList<String> pathHTTP,
                       ArrayList<String> labelText) throws IOException {

    //Build the Json String
    JsonFileDownloader jfd = new JsonFileDownloader();
   // jsonData = String.valueOf(jfd.execute(promo));
    jfd.execute(promo);
    //jfd.getResuts(jsonData);
    //jsonData = jfd.ret;

    Log.d("JsonData String = " , jsonData);


    //Try to parse the data
    try
    {

        Log.d("Jsondata " , jsonData);
        //Creaate a new JSONObject ith the name/value mapping from the JSON string
        jsonResponse = new JSONObject(jsonData);
        //Returns the value mapped by the name if it exists and is a JSONArry
        JSONArray jsonMainNode = jsonResponse.optJSONArray("");

        //Proccess the JSON node
        int lenghtJsonArrar = jsonMainNode.length();
        for (int i = 0; i<lenghtJsonArrar; i++)
        {
            //Get object for each json node
            JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
            //Get the node values
            //int song_id = Integer.parseInt(jsonChildNode.optString("song_id").toString());
            String picture = jsonChildNode.optString("picture").toString();
            String pathName = jsonChildNode.optString("path").toString();
            String lableName = jsonChildNode.optString("label".toString());
            //Debug Testing code
            pictureHTTP.add(picture);
            pathHTTP.add(pathName);
            labelText.add(lableName);


        }

    } catch (JSONException e) {
        e.printStackTrace();
    }

}

现在我知道问题出在哪里了。当我尝试为 jsonData 分配一个值时,它永远不会被分配,因此它为空并且系统失败。 我在 jfd.exicute() 之后尝试了一些东西,但我只是不知道如何将最终字符串输出中的值获取到 jsonData 中。 感谢您对此的任何帮助。

【问题讨论】:

  • 仅仅因为你在执行JsonFileDownloader 之后放置了try 块并不意味着AsyncTask 将在那时完成处理。相反,使用AsyncTask 中的onPostExecute 来处理返回值

标签: java android json android-asynctask


【解决方案1】:

好的,这是一个非常灵活的模式,用于使用 AsyncTask 下载 Web 内容并将结果返回给 UI 线程。

第 1 步 定义一个接口,该接口将充当 AsyncTask 和您想要数据的位置之间的消息总线。

public interface AsyncResponse<T> {
    void onResponse(T response);
}

第 2 步 创建一个通用的 AsyncTask 扩展,它将接受任何 URL 并从中返回结果。你基本上已经有了这个,但我做了一些调整。最重要的是,允许设置 AsyncResponse 回调接口。

public class WebDownloadTask extends AsyncTask<String, Void, String> {

    private AsyncResponse<String> callback;

    // Optional parameters
    private String username;
    private String password;

    // Make a constuctor to store the parameters
    public WebDownloadTask(String username, String password) {
        this.username = username;
        this.password = password;
    }

    // Don't forget to call this
    public void setCallback(AsyncResponse<String> callback) {
        this.callback = callback;
    }

    @Override
    protected String doInBackground(String... params) {
        String url = params[0];
        return readFromFile(url);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if (callback != null) {
            callback.onResponse(s);
        } else {
            Log.w(WebDownloadTask.class.getSimpleName(), "The response was ignored");
        }
    }

    /******* private helper methods *******/

    private String streamToString(InputStream is) throws IOException {

        StringBuilder sb = new StringBuilder();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        while ((line = rd.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }

    private String readFromFile(String myWebpage) {

        String response = null;
        HttpURLConnection urlConnection = null;

        try {
            //Get the url connection
            URL url = new URL(myWebpage);

            // Unnecessary for general AsyncTask usage
            /* 
            Authenticator.setDefault(new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password.toCharArray());
                }
            });
            */

            urlConnection = (HttpURLConnection) url.openConnection();

            InputStream inputStream = urlConnection.getInputStream();

            if (inputStream != null) {
                response = streamToString(inputStream);
                inputStream.close();
                Log.d("Final String", response);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }

        return response;
    }
}

第 3 步继续并在任何您希望的地方使用该 AsyncTask。这是一个例子。请注意,如果您不使用setCallback,您将无法获取来自 AsyncTask 的数据。

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WebDownloadTask task = new WebDownloadTask("username", "password");
        task.setCallback(new AsyncResponse<String>() {
            @Override
            public void onResponse(String response) {
                // Handle response here. E.g. parse into a JSON object
                // Then put objects into some list, then place into an adapter... 
                Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
            }
        });

        // Use any URL, this one returns a list of 10 users in JSON
        task.execute("http://jsonplaceholder.typicode.com/users");
    }
}

【讨论】:

  • 是的,修复了它,我不知道我必须制作一个 Asynctask 界面,这真的很有帮助。非常感谢!
  • 不必必须,这只是使用标准 Java 库将接口用作异步回调的常见模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
相关资源
最近更新 更多