等待2个asynctasks

时间:2014-03-08 15:39:01

标签: java android json android-asynctask synchronization

您好我正在处理大声笑的应用程序,我遇到了异步任务和从2个不同的json源获取数据的问题。我需要做的是从1个json源获取一些信息(获取英雄id),然后将该信息提供给另一个任务以获取英雄的名字(另一个json源),然后将来自两个源的信息保存到arraylist中。我不知道如何使这两个异步任务等待对方然后写下数据。在我设法解决这个问题之前,使用静态字段并从1个任务中保存数据,然后将其提供给第二个任务,但我确定有另一种方法而不需要使用字段,我希望以这种方式完成体验好吧...现在我也使用了loopj库但我仍然无法组合异步任务。我不能为你提供lol api密钥,因为它应该是私密的,但我希望有人能够帮助我。提前谢谢。

    package com.example.lolscouterv2;

import java.io.Console;
import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;


import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;

import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import com.loopj.android.http.*;

public class SummonerGames extends ListActivity {
    String summonerNameId, summonerRegion;
    String finalURL1 = "https://prod.api.pvp.net/api/lol/";
    String finalURL3 =  "/v1.3/game/by-summoner/";
    String finalURL2 = "/recent?api_key=";
    String finalURL;
    JSONArray jsonArray, jArr;
    HashMap <String, String> map;
    JSONObject c1, c2, jArr1, c3;
    String champID = null;
    String champURL1="https://prod.api.pvp.net/api/lol/static-data/eune/v1/champion/";
    String champURL2 = "?api_key=";
    String urlChampion;
    ArrayList<HashMap<String, String>> summonerGames, summonerChamp;
    static String heroID = null;
    static boolean completed = true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.summonergames);
        summonerNameId = getIntent().getStringExtra("summonerName");
        summonerRegion = getIntent().getStringExtra("summonerRegion");
        finalURL = finalURL1 + summonerRegion  + finalURL3 + summonerNameId + finalURL2;
        Toast.makeText(SummonerGames.this, finalURL, Toast.LENGTH_SHORT).show();
        summonerGames = new ArrayList<HashMap<String,String>>();
        final AsyncHttpClient client = new AsyncHttpClient();
        client.get(finalURL, new JsonHttpResponseHandler(){
            @Override
            public void onSuccess(JSONObject response) {
                String kills = null, numOfDeaths = null, assists = null, minions = null;

                try {
                    jsonArray = response.getJSONArray("games");
                } catch (JSONException e) {

                    e.printStackTrace();
                }


                for (int i = 0; i < jsonArray.length(); i++){
                    map = new HashMap<String, String>();
                    try {
                        c1 = jsonArray.getJSONObject(i);
                    } catch (JSONException e) {

                        e.printStackTrace();
                    }

                    try {
                        jArr = c1.getJSONArray("fellowPlayers");
                    } catch (JSONException e1) {

                        e1.printStackTrace();
                    }


                    /*for (int j = 0; j < jArr.length(); j++){
                        String testSummonerId = null;
                    try {
                        jArr1 = jArr.getJSONObject(j);
                        //testSummonerId = jArr.getString(2);

                        Log.i("TEST", jArr1.toString());
                    } catch (JSONException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }

                    try {
                        testSummonerId = jArr1.getString("summonerId");
                        Log.i("TEST222", testSummonerId);
                    } catch (JSONException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    Log.i("ERROR", testSummonerId);
                    Log.i("ERROR2", summonerNameId);
                    if(Integer.parseInt(summonerNameId)== Integer.parseInt(testSummonerId)){
                        try {
                            champID = jArr1.getString("championId");

                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();

                        }
                    }
                    map.put("heroid", champID);
                    }*/





                    try {
                        c2 = c1.getJSONObject("stats");
                    } catch (JSONException e) {

                        e.printStackTrace();
                    }

                    try {
                        heroID = c1.getString("championId");
                    } catch (JSONException e1) {

                        e1.printStackTrace();
                    }
                    String level = null;

                    urlChampion = champURL1 + heroID + champURL2;

                    try {
                        level = c2.getString("level");
                    } catch (JSONException e) {

                        e.printStackTrace();
                    }

                    if (c2.isNull("championsKilled")){
                        kills = "0";

                    }
                    else{
                    try {
                        kills = c2.getString("championsKilled");
                    } catch (JSONException e) {

                        e.printStackTrace();
                    }
                    }
                    if (c2.isNull("numDeaths"))
                        numOfDeaths = "0";
                    else
                        try {
                            numOfDeaths = c2.getString("numDeaths");
                        } catch (JSONException e) {

                            e.printStackTrace();
                        }
                    if (c2.isNull("assists"))
                        assists = "0";
                    else
                        try {
                            assists = c2.getString("assists");
                        } catch (JSONException e) {

                            e.printStackTrace();
                        }
                    if (c2.isNull("minionsKilled"))
                        minions = "0";
                    else
                        try {
                            minions = c2.getString("minionsKilled");
                        } catch (JSONException e) {

                            e.printStackTrace();
                        }
                    String neutralMinions = null;
                    if (c2.isNull("neutralMinionsKilled")){

                    neutralMinions = "0";
                    }
                    else{
                         try {
                            neutralMinions = c2.getString("neutralMinionsKilled");
                        } catch (JSONException e) {

                            e.printStackTrace();
                        }
                    }
                    int totalMinions = Integer.parseInt(minions)+ Integer.parseInt(neutralMinions);

                    String gold = null;
                    try {
                        gold = c2.getString("goldEarned");
                    } catch (JSONException e) {

                        e.printStackTrace();
                    }
                    float gold1 = Float.parseFloat(gold)/1000; 
                    boolean gameEnd = false;
                    try {
                        gameEnd = c2.getBoolean("win");
                    } catch (JSONException e) {

                        e.printStackTrace();
                    }
                    String gameResult;

                    if(gameEnd)
                        gameResult = "win";
                    else
                        gameResult = "lose";
                    int x = 0;
                    String data = getChamp(urlChampion);

                    while (completed){
                        x = x + 1;
                        System.out.print(x);

                    }

                    x = 0;

                    map.put ("kills", kills);
                    map.put ("assists", assists);
                    map.put ("deaths", numOfDeaths);
                    map.put ("level", "Level:" + level);
                    map.put("goldEarned", "Gold:" + String.valueOf(gold1) +"k");
                    map.put("gameResult", gameResult);
                    map.put("minions", "Minions:" + String.valueOf(totalMinions));
                    map.put("heroid", data);
                    summonerGames.add(map);
                    completed = true;
                }
                Log.i("test", jsonArray.toString());

                ListAdapter adapter = new SimpleAdapter(SummonerGames.this, summonerGames, R.layout.list_items,
                        new String[] { "kills", "assists",
                        "deaths", "goldEarned", "minions", "gameResult", "level", "heroid" }, new int[] { R.id.kills,
                        R.id.assists, R.id.deaths, R.id.gold, R.id.minions, R.id.gameStatus, R.id.heroLevel, R.id.heroName });

                setListAdapter(adapter);
            }
        });
    }

    static public String getChamp(String url){
        AsyncHttpClient client1 = new AsyncHttpClient();



        client1.get(url, new JsonHttpResponseHandler(){
            @Override
            public void onSuccess(JSONObject response1){
                try {
                    heroID = response1.getString("name");
                    Log.i("TESTNAME", heroID);
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                completed = false;
            }

        });






        return heroID;

    }
}

2 个答案:

答案 0 :(得分:1)

如果您正在使用loopj,则调用已经异步,因此您不需要自己进行调用。您无法从 getChamp()方法返回 heroId ,因为它是在您的案例中的内部类 new JsonHttpResponseHandler(){} 中初始化的。我的猜测是你的异步调用确实在等待彼此,但是根据我之前的解释,你根本就没有从第二个调用中得到结果。我建议你看看回调接口,看看如何使用它们。我要做的是,创建一个回调接口,并在你的通话的 onSuccess 中使用它将heroId(或任何返回值)传递回你的主类。这是一个粗略的想法:

public MyClass implements GetHeroListener{

private GetHeroListener getHeroListener;
public interface GetHeroListener {
    public void getHeroCallback(String heroName);
}

@Override
public void getHeroCallback(String heroName) {
    //here you now get your data from the onSuccess and can do whatever you want example:
    makeNewHTTPCallToGetHeroDetails(myUrl, heroName);
}

static public String getChamp(String url){
    getHeroListener = (GetHeroListener) this; //this is the part where you "connect" your main class to your listner

    AsyncHttpClient client1 = new AsyncHttpClient();

    client1.get(url, new JsonHttpResponseHandler(){
        @Override
        public void onSuccess(JSONObject response1){
            try {
                heroID = response1.getString("name");
                getHeroListener.getHeroCallback(heroID); //this is the part where you call the interfaces listener method, it will call back to the class that implements it, just make sure you override the method 
                Log.i("TESTNAME", heroID);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            completed = false;
        }

    });
}

答案 1 :(得分:0)

如果你只在蜂窝及以上版本上运行应用程序,请注意默认情况下AsyncTask在单个线程上运行,因此您只需创建并执行3个asyncTasks即可。每个人都会追逐另一个。

如果你想支持旧版本的android,你可以自定义当前的AsyncTask线程池,也可以复制AsyncTask的代码:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.2_r1/android/os/AsyncTask.java?av=f