我正在构建一个请求服务器温度的应用程序。当按下按钮时,我希望应用程序能够:
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。是这样吗,我应该避免在 App 中使用 Runnable 和 Thread 吗?
我对问题 3 最感兴趣,因为许多 stackoverflow 答案都指向使用 Runnable 和 Thread 技术来完成网络,现在我在这里我担心我已经浪费了很多时间和精力。感谢阅读,欢迎为新的应用程序开发人员(或 stackoverflow 用户!)提供任何一般提示和建议。
最佳答案
result = task.get();
get()
是一种阻塞方法。它会一直等到 T
可用才能返回。这就是“MainActivity 等待它完成”的原因。
Is that true, and should I avoid using Runnable and Thread in an App?
不,不是。当不允许我使用第三方库向网络服务发送请求时,我使用 ExecutorService
。
Why does onClick execute at the end, unlike traditional scripting languages which execute line by line?
最后不执行。您正在向您的 mFetchTempButton
提供委托(delegate),回调中的代码 onClick
在点击事件发生时执行。
关于java - Android - 使用 Callable 进行联网,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34474073/