简体   繁体   中英

synchronized between the main thread of android and another thread

Android by design doesn't allow network on the main thread it can be forced but its not a good practice. So I want to synchronized the main thread and one other thread so I can get the response from the database for user authentication. My synchronization is not working..

This is the code in the main thread..

if (loginBTN.getId() == ((Button) v).getId()) {

    String emailId = loginField.getText().toString().trim();
    String password = passwordField.getText().toString().trim();

    postParameters.add(new BasicNameValuePair("username", emailId));
    postParameters.add(new BasicNameValuePair("password", password));

    try {

        System.out.println("b4 response" + responseToString);

        checkLogin();

        System.out.println("after response" + responseToString);

        synchronized (this) {

            while (isAvailable == false) {

                wait();

            }

            if (responseToString.equalsIgnoreCase("1")) {

                statusLBL.setText("Login Successful...");

            }

            else {

                statusLBL.setText("Sorry Incorrect Username or Password...");

            }
        }

    }

    catch (Exception e) {

        statusLBL.setText(e.toString());
    }

}




private void checkLogin() {

        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {

                try {

                    HttpClient http = new DefaultHttpClient();
                    HttpPost request = new HttpPost("http://example.org/api/android_gradhub/login_user.php");
                    UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
                    request.setEntity(formEntity);
                    HttpResponse response = http.execute(request);
                    HttpEntity entity = response.getEntity();

                    // responseToString = EntityUtils.toString(entity);

                    synchronized (this) {

                        while (isAvailable == true) {

                            wait();

                        }

                        responseToString = EntityUtils.toString(entity);
                        notifyAll();
                    }

                    System.out.println("response " + responseToString);
                }

                catch (Exception e) {

                    e.printStackTrace();
                }
            }
        });

        thread.start();

    }

Remove all of your synhronization and then just put thread.join() as the last statement in checkLogin . This is the simplest way to wait for the thread to complete before proceeding.

If you want to decide when to wait (like you might want to do other stuff in the main program before the login needs to be checked) then you can return the thread from checkLogin . Than you decide when to join back in your main program. (ie signature changes to public Thread checkLogin and last line of checkLogin becomes return thread . Back in your main program, call Thread thread = checkLogin(); when you want to wait for the checkLogin to finish - use thread.join() , up until that point Main thread and checkLogin thread is concurrent).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM