如何通过 asyncTask 方法解析来自 2 个不同 URL 的数据
Posted
技术标签:
【中文标题】如何通过 asyncTask 方法解析来自 2 个不同 URL 的数据【英文标题】:How to parse data from 2 different URLs by asyncTask method 【发布时间】:2013-12-12 21:54:36 【问题描述】:我有一个从 JSON URL 获取数据的应用。它与一个 URL 完美配合,但我需要同时从两个 JSON URL 获取数据。就像来自一个 URL 的一些数据和来自另一个 URL 的一些数据。并在两个 textView 中显示它们。
这是我的应用,它目前不加载任何数据。
MainActivity:
public class MainActivity extends Activity
//URL to get JSON Array
private static String url1 = "http://api.worldbank.org/countries/de?format=json";
private static String url2 = "http://api.worldbank.org/countries/it?format=json";
//JSON Node Names
private static final String CountryNAME1 = "name";
private static final String CountryNAME2 = "name";
JSONArray user = null;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new GetJSONTask().execute(url1);
//new GETJSONTask().execute(url2);
class GetJSONTask extends AsyncTask<String, Void, JSONObject>
protected JSONObject doInBackground(String... urls)
// Creating new JSON Parser
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONObject json1 = jParser.getJSONFromUrl(url1);
JSONObject json2 = jParser.getJSONFromUrl(url2);
return json1;
protected void onPostExecute(JSONObject json1, JSONObject json2)
//Getting JSON Array
try
//For Country 1
// Get the array
JSONArray countryArC1 = json1.getJSONArray("myValues");
JSONObject countryObC1 = countryArC1.getJSONObject(0);
JSONArray countryAr2C1 = countryArC1.getJSONArray(1);
JSONObject countryOb2C1 = countryAr2C1.getJSONObject(0);
//For Country 2
// Get the array
JSONArray countryArC2 = json2.getJSONArray("myValues");
JSONObject countryObC2 = countryArC2.getJSONObject(0);
JSONArray countryAr2C2 = countryArC2.getJSONArray(1);
JSONObject countryOb2C2 = countryAr2C2.getJSONObject(0);
//Storing JSON item in a Variable
String name1 = countryOb2C1.getString(CountryNAME1);
String name2 = countryOb2C2.getString(CountryNAME2);
//Importing TextView
final TextView textView1 = (TextView)findViewById(R.id.url1);
final TextView textView2 = (TextView)findViewById(R.id.url2);
//Set JSON Data in TextView
textView1.setText(name1);
textView2.setText(name2);
catch (JSONException e)
// TODO Auto-generated catch block
e.printStackTrace();
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
JSONParser:
public class JSONParser
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser()
public JSONObject getJSONFromUrl(String url)
//System.out.println("url getJSONfromUrl " + url);
//url = "http://api.worldbank.org/countries/CA/indicators/SP.POP.TOTL?date=1980:1981&format=json";
// Making HTTP request
try
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
catch (UnsupportedEncodingException e)
e.printStackTrace();
catch (ClientProtocolException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
try
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
sb.append(line + "\n");
is.close();
json = sb.toString();
System.out.println("JSONParser string: " + json);
catch (Exception e)
Log.e("Buffer Error", "Error converting result " + e.toString());
// try parse the string to a JSON object
try
jObj = new JSONObject(json);
catch (JSONException e)
Log.e("JSON Parser", "Error parsing data " + e.toString());
if (json.startsWith("["))
// We have a JSONArray
try
jObj = new JSONObject();
jObj.put("data", new JSONArray(json));
catch (JSONException e)
Log.d("JSON Parser", "Error parsing JSONArray " + e.toString());
return jObj;
// try parse the string to a JSON object
/*try
jObj = new JSONObject(json);
catch (JSONException e)
Log.e("JSON Parser", "Error parsing data " + e.toString());
*/
// return JSON String
return jObj;
XML:
<TextView
android:id="@+id/url1"
android:layout_
android:layout_
/>
<TextView
android:id="@+id/url2"
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:layout_below="@+id/url1"
android:layout_marginTop="104dp"
/>
我认为主要问题是 new GetJSONTask().execute(url1);
和 JSONObject json1 = jParser.getJSONFromUrl(url1);
因为我不能有 2 个 GetJSONTASK,也不能同时返回 json1 和 json2。
有什么想法吗?
【问题讨论】:
【参考方案1】:我建议你改变你的方法
class GetJSONTask extends AsyncTask<String, Void, JSONObject[]>
...
protected JSONObject[] doInBackground(String... urls)
// Creating new JSON Parser
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONObject[] jsons = new JSONObject[2];
jsons[0] = jParser.getJSONFromUrl(url1);
jsons[1] = jParser.getJSONFromUrl(url2);
return jsons;
protected void onPostExecute(JSONObject[] jsons)
JSONObject json1 = jsons[0];
JSONObject json2 = jsons[1];
// do you work after this
希望对您有所帮助!
【讨论】:
【参考方案2】:变体 A) 您可以像这样执行 GetJSONTask
:
new GetJSONTask().execute(url1, url2);
并像这样访问 AsyncTask 中的 URL:
class GetJSONTask extends AsyncTask<String, Void, JSONObject[]>
...
JSONObject[] doInBackground(String... urls)
// Getting JSON from URL
JSONObject json1 = jParser.getJSONFromUrl(urls[1]);
JSONObject json2 = jParser.getJSONFromUrl(url2[2]);
return new JSONObject[] json1, json2;
void onPostExecute(JSONObject[] jsons) ...
变体 B) 如果您想让进程真正并行运行,您可以添加另一个 AsyncTask,它创建 2 个子任务并等待它们的结果。在大多数设备上,这将是执行该任务所需时间的一半。
class GetTwoJsonsTask extends AsyncTask<String, Void, JSONObject[]>
JSONObject[] doInBackground(urls)
task1 = new GetJSONTask().execute(urls[1]);
task2 = new GetJSONTask().execute(urls[2]);
// block until sub-tasks are finished
JSONObject json1 = task1.get();
JSONObject json2 = task2.get();
return new JSONObject[] json1, json2;
void onPostExecute(JSONObject[] jsons) ...
【讨论】:
感谢您的帮助。但有一个问题。它像return new JSONObject[] json1, json2;
这样出错,这就是原因:Type mismatch: cannot convert from JSONObject[] to JSONObject
您需要在泛型 AsyncTask 中提供正确的类型:GetJSONTask extends AsyncTask<String, Void, JSONObject[]>
【参考方案3】:
我就是这样做的,方法很简单
public class GetSetting extends AsyncTask<List<String>,Void,List<String>>
String urls[] = new String[]"http:// first url",
"http:// second url";
@Override
protected ArrayList<String> doInBackground(List<String>... lists)
HttpURLConnection urlConnection;
InputStream inputStream;
BufferedReader bufferedReader;
URL urlIfSup;
ArrayList<String> result = new ArrayList<>();
try
// here to connect and get a different type of data
for (int i = 0; i < 2; i++) // this one for connect the url from url array in every loop
urlIfSup = new URL(urls[i]);
urlConnection = (HttpURLConnection) urlIfSup.openConnection();
inputStream = urlConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
String data = bufferedReader.readLine();
while(bufferedReader.readLine() != null)
data += bufferedReader.readLine();
if (i==0)
// do something for the first url
else if (i==1)
// do something for the second url
// use jSON if you want
// then do this at the last url
urlConnection.disconnect();
inputStream.close();
bufferedReader.close();
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
return result;
【讨论】:
以上是关于如何通过 asyncTask 方法解析来自 2 个不同 URL 的数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在Android开发中用AsyncTask异步更新UI界面