0

I've tried to implement a asynctask in another asynctask, but it got stuck. When I clicked the buttun to trigger the first asynctask, the second asynctask in the first one does not execute when the first is completed and when I tried to click the button again, the button gave no response.

java:

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

String task = "";
Context context;
String user_name = "";
String user_ac = "";
String user_pw = "";

BackgroundTask (Context ctx){
    context = ctx;
}

@Override
protected String doInBackground(String... params) {
    String register_url = "http://www.minigameserver.square7.ch/register.php";
    String login_url = "http://www.minigameserver.square7.ch/login.php";
    String get_userID_url = "http://www.minigameserver.square7.ch/get_userID.php";
    String task_url = "";
    task = params[0];

    if(task.equals("register")){
        task_url = register_url;
        user_name = params[1];
        user_ac = params[2];
        user_pw = params[3];
    }
    if(task.equals("login")){
        task_url = login_url;
        user_ac = params[1];
        user_pw = params[2];
    }
    if(task.equals("get_userID")){
        task_url = get_userID_url;
        user_ac = params[1];
    }
        try {
            URL url = new URL(task_url);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.connect();
            OutputStream OS = httpURLConnection.getOutputStream();
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(OS, "UTF-8"));
            String data = "";
            if(task.equals("register")){
                data = URLEncoder.encode("user_name", "UTF-8") + "=" + URLEncoder.encode(user_name, "UTF-8") + "&" +
                        URLEncoder.encode("user_ac", "UTF-8") + "=" + URLEncoder.encode(user_ac, "UTF-8") + "&" +
                        URLEncoder.encode("user_pw", "UTF-8") + "=" + URLEncoder.encode(user_pw, "UTF-8");
            }
            if(task.equals("login")){
                data = URLEncoder.encode("user_ac", "UTF-8") + "=" + URLEncoder.encode(user_ac, "UTF-8") + "&" +
                        URLEncoder.encode("user_pw", "UTF-8") + "=" + URLEncoder.encode(user_pw, "UTF-8");
            }
            if(task.equals("get_userID")){
                data = URLEncoder.encode("user_ac", "UTF-8") + "=" + URLEncoder.encode(user_ac, "UTF-8");
            }
            bufferedWriter.write(data);
            bufferedWriter.flush();
            bufferedWriter.close();
            OS.close();

            int responseCode = httpURLConnection.getResponseCode();
            if (responseCode == 200) {
                InputStream IS = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IS));
                StringBuilder result = new StringBuilder();
                String getresult = "";
                while ((getresult = bufferedReader.readLine()) != null) {
                    result.append(getresult);
                }
                bufferedReader.close();
                IS.close();
                String result_newline = result.toString();
                result_newline = result_newline.replace("\\n", System.getProperty("line.separator"));
                return result_newline;
            }

            httpURLConnection.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "fail!";

}

@Override
protected void onPostExecute(String result) {
    super.onPreExecute();
    if(task.equals("get_userID")){
        MainActivity.user_ID = result;
        Toast.makeText(context,"GET",Toast.LENGTH_LONG);
    }
    if(task.equals("register") || task.equals("login")){
        //Toast.makeText(context,result,Toast.LENGTH_LONG).show();
        BackgroundTask get_userID_task = new BackgroundTask(context);
        get_userID_task.execute("get_userID",user_ac);
    }

}
}

I implemented the second asynctask in the onPostExecute of the first one. Can anyone point out where I got wrong?


Update:

    if(task.equals("register") || task.equals("login")){
        MainActivity.user_ID = result;
        Toast.makeText(context,MainActivity.user_ID,Toast.LENGTH_LONG).show();
        //BackgroundTask get_userID_task = new BackgroundTask(context);
        //get_userID_task.execute("get_userID",user_ac);
    }

The message showed what I expected. When I commented out the second asynctask, the button still could not trigger again. When I ommented out MainActivity.user_ID = result; and related stuff, the button could trigger again.


Update2:

java:

public interface AsyncResponse {
    void processFinish();
}

public class BackgroundTask extends AsyncTask<String, Void, String>{
    AsyncResponse delegate = null;
    ...
        protected void onPostExecute(String result) {
            ...
            delegate.processFinish();
        }
}

// MainActivity has a button to go to login 
public class login extends AppCompatActivity implements AsyncResponse{
    ...
    BackgroundTask backgroundTask = new BackgroundTask(this);
    backgroundTask.delegate = this;
    backgroundTask.execute("login",user_ac_s,user_pw_s);

    public void processFinish(){
    if(!MainActivity.user_ID.equals("0"))
        finish();
    }
}

Actually, I want to finish the login page and go back to MainActivity after getting the user ID from Asynctask. But, it stopped unfortunately when the user login successfully.

New post: android - finish the current activity only after the asynctask finishes

Community
  • 1
  • 1
Keroro Chan
  • 99
  • 1
  • 10
  • 1
    Click what button? The second AsyncTask *should* be running, as that is what you told the code to do. However, `MainActivity.user_ID = result` is a problem - static variables are overall not how you pass data to activities – OneCricketeer Aug 04 '16 at 02:47
  • Alternative solution to prevent double network requests, which drains the battery - Have login and register actually return the User ID – OneCricketeer Aug 04 '16 at 02:48
  • @cricket_007 user_ID is the variable in MainActivity and the result is got from asynctask by MainActivity.user_ID = result, isn't it? – Keroro Chan Aug 04 '16 at 02:50
  • @cricket_007 As login and register return some strings and I don't want mix them up, I separate another php to return user ID and that's why I use 2 network requests. – Keroro Chan Aug 04 '16 at 02:54
  • You could return a JSON object from PHP with all the data you need. It is setting the value, but that's a bad "pattern" to return a result from an AsyncTask overall. Do to that appropriately, you can check out this post. https://stackoverflow.com/questions/9458258/return-a-value-from-asynctask-in-android – OneCricketeer Aug 04 '16 at 02:55
  • @cricket_007 MainActivity.user_ID = result works fine. Please view my updated code above. – Keroro Chan Aug 04 '16 at 03:00
  • I'm not saying it doesn't work - but the ID value will be unassigned before either of the tasks finishes. Just be aware of that. Anyways, I feel like this "recursion" works. Are you claiming it doesn't because the Toast doesn't display? – OneCricketeer Aug 04 '16 at 03:05
  • @cricket_007 Yes, the Toast doesn't display in the second asynctask. Also, when I commented out the second asynctask, the button could not trigger again. When I commented out MainActivity.user_ID = result; and related stuff, the button could trigger again. I think there is something wrong about MainActivity.user_ID. – Keroro Chan Aug 04 '16 at 03:07
  • Can you try to `Log` a message instead? That context variable may not be reliable in the second task. – OneCricketeer Aug 04 '16 at 03:10
  • @cricket_007 I forgot I have set if-statement. I think it should be OK. It is nice to point out that the battery runs out quickly when I use 2 requests. I think it is OK for my case as the login process will not do so many times. – Keroro Chan Aug 04 '16 at 03:21
  • Did you `debug` to check that the 2nd AsyncTask is executed? – Neo Aug 04 '16 at 03:44
  • @MrNeo Yes, it indeed execute but I don't know why the toast doesn't come up. – Keroro Chan Aug 04 '16 at 03:46
  • Could you please `Log` the `task` value and post the result? As @cricket_007 said, this could be "recursion" – Neo Aug 04 '16 at 03:48
  • user ID: 30 something like that. – Keroro Chan Aug 04 '16 at 03:49
  • Another way to check this is to watch the traffic on your server to see if two requests are made – OneCricketeer Aug 04 '16 at 03:52
  • @cricket_007 I see. Thanks. – Keroro Chan Aug 04 '16 at 03:52
  • @cricket_007 One more thing, how can I wait until the second asynctask finishes so that the remaining code executes after that? – Keroro Chan Aug 04 '16 at 03:54
  • Callbacks ;) Which is what I tried to link before, but that was the wrong post - here is the correct one. https://stackoverflow.com/questions/12575068/how-to-get-the-result-of-onpostexecute-to-main-activity-because-asynctask-is-a – OneCricketeer Aug 04 '16 at 03:57
  • I mean could you please check `task` is "get_userID" or other? Put break point to `if(task.equals("get_userID")){ MainActivity.user_ID = result; Toast.makeText(context,"GET",Toast.LENGTH_LONG); }` and check did it executed? – Neo Aug 04 '16 at 04:02
  • @MrNeo it is OK now. – Keroro Chan Aug 04 '16 at 04:04
  • @cricket_007 My case is that I executed the second asynctask and got the value of user ID. However, the remaining code `if(!MainActivity.user_ID.equals("0")) finish();` to finish the current activity but it doesn't finish the activity even the value of user ID is got. And, when I pressed the button again, it finished. I want to finish the activity when the result is got. – Keroro Chan Aug 04 '16 at 04:10
  • @cricket_007 the link provides a way to get result and I've already finished. But, how can I wait until all synctasks finish? – Keroro Chan Aug 04 '16 at 04:26
  • You put a callback at the very end of the onPostExecute. You can pass along the "delegate" just like the "context" variable. – OneCricketeer Aug 04 '16 at 04:28
  • Could you mind to post some code here? – Keroro Chan Aug 04 '16 at 04:29
  • @cricket_007 I see what you mean. I try to implement. – Keroro Chan Aug 04 '16 at 04:32
  • @cricket_007 I got an error. Please view my update2. I implement an interface and the app stopped unexpectedly. – Keroro Chan Aug 04 '16 at 05:23
  • Try to post a new question including the error log – OneCricketeer Aug 04 '16 at 05:33
  • @cricket_007 new question here: http://stackoverflow.com/questions/38759301/android-finish-the-current-activity-only-after-the-asynctask-finishes – Keroro Chan Aug 04 '16 at 05:48

0 Answers0