Android - 使用Callable进行网络连接

时间:2015-12-26 18:34:02

标签: java android multithreading android-asynctask runnable

我正在构建一个请求服务器温度的应用程序。按下按钮时,我希望应用程序:

1)显示“联系服务器”消息并显示旋转进度条。

2)在新线程上联系服务器。

3)显示结果并隐藏进度条。

这是我的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);
        }
    });

    }
}

这将调用java类'RequestServerTemp',它使用Callable在新线程上发出服务器请求:

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";
    }
}

这导致的错误是应用程序仅在整个onClick完成后才更新。这可以防止我发生所需的步骤1)。我是Android新手,这为我提出了几个问题:

1)为什么onClick会在最后执行,这与逐行执行的传统脚本语言不同?

2)如果我在新线程中启动了RequestServerTemp,为什么MainActivity会等待它完成?我认为这对应用程序来说是不好的,这样的延迟是我们在新线程中启动网络的全部原因。

3)几个类似的问题说AsyncTask是处理网络的“正确”方式,而不是Runnable或Thread。这是真的,我应该避免在应用程序中使用Runnable和Thread吗?

我最感兴趣的是问题3,因为许多stackoverflow答案指向使用Runnable和Thread技术来完成网络,现在我在这里我担心我浪费了大量的时间和精力。感谢您阅读,欢迎任何针对新应用开发者(或stackoverflow用户!)的一般提示和建议。

1 个答案:

答案 0 :(得分:0)

result = task.get();

get()是一种阻止方法。它会一直等到T可用。这就是为什么&#34; MainActivity等待它完成&#34;。

  

是真的,我应该避免在App中使用Runnable和Thread吗?

不,不是。当我不被允许使用第三方库向Web服务发送请求时,我使用ExecutorService

  

与传统脚本不同,为什么onClick最终会执行   逐行执行的语言?

它最后没有执行。您正在为mFetchTempButton提供代理,回调中的代码onClick会在点击事件发生时执行。