简体   繁体   中英

Android - Using Callable for networking

I am building an app that requests the temperature of a server. When a button is pressed, I would like the app to:

1) Show a 'contacting server' message and show a spinning progress bar.

2) Contact the server on a new thread.

3) Display the result and hide the progress bar.

Here is my MainActivity:

public class MainActivity extends AppCompatActivity {

private Button mFetchTempButton;
private TextView mResultTextView;
private ProgressBar mProgressBar;

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

    mResultTextView = (TextView) findViewById(R.id.result_textview);
    mFetchTempButton = (Button) findViewById(R.id.fetch_temperature_button);
    mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);

    mFetchTempButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mResultTextView.setText("Contacting server... ");
            mProgressBar.setVisibility(View.VISIBLE);
            String[] args = {};
            String temperature = RequestServerTemp.main(args);
            mProgressBar.setVisibility(View.INVISIBLE);
            mResultTextView.setText("Server temperature is " + temperature);
        }
    });

    }
}

This calls the java class 'RequestServerTemp', which uses a Callable to make the server request on a new thread:

public class RequestServerTemp {

    public static String main(String[] args) {
        final ExecutorService service;
        final Future<String> task;
        String result = "";

        service = Executors.newFixedThreadPool(1);
        task = service.submit(new GetTemp());

        try {
            result = task.get();
        }
        catch(InterruptedException | ExecutionException ex) {
            ex.getMessage();
        }
        service.shutdownNow();
        return result;
    }
}

class GetTemp implements Callable<String> {
    public String call() {

        // simulate a long networking operation
        try {
            Thread.sleep(3*1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "30 degrees C";
    }
}

The error this causes is that the App only updates once the whole onClick has been completed. This prevents my required step 1) from occurring. I am new to Android, and this raises several questions for me:

1) Why does onClick execute at the end, unlike traditional scripting languages which execute line by line?

2) If I've launched RequestServerTemp in a new Thread, why does MainActivity wait for it to finish? I feel this is bad for an app, and delays like this are the whole reason we launch networking in new threads.

3) Several similar questions to this say that AsyncTask is the 'correct' way to handle networking, rather than Runnable or Thread. Is that true, and should I avoid using Runnable and Thread in an App?

I am mostly interested in question 3, as many stackoverflow answers point to using Runnable and Thread techniques to accomplish networking, and now I am here I am worried I've wasted a lot of time and effort. Thanks for reading, and any general hints and advice for a new app developer (or stackoverflow user!) are welcome.

result = task.get();

get() is a blocking method. It waits until T is available to be returned. That's why "MainActivity wait for it to finish".

Is that true, and should I avoid using Runnable and Thread in an App?

No it is not. When I am not allowed to use third party library to send requests to a webservice, I use an ExecutorService .

Why does onClick execute at the end, unlike traditional scripting languages which execute line by line?

it does not execute at the end. You are providing a delegate to your mFetchTempButton , the code in the callback, onClick , is executed when the event on click takes place.

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