我正在构建一个请求服务器温度的应用程序。按下按钮时,我希望应用程序:
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用户!)的一般提示和建议。
答案 0 :(得分:0)
result = task.get();
get()
是一种阻止方法。它会一直等到T
可用。这就是为什么&#34; MainActivity等待它完成&#34;。
是真的,我应该避免在App中使用Runnable和Thread吗?
不,不是。当我不被允许使用第三方库向Web服务发送请求时,我使用ExecutorService
。
与传统脚本不同,为什么onClick最终会执行 逐行执行的语言?
它最后没有执行。您正在为mFetchTempButton
提供代理,回调中的代码onClick
会在点击事件发生时执行。