Android - 使用 Callable 进行联网
Android - Using Callable for networking
我正在构建一个请求服务器温度的应用程序。按下按钮时,我希望应用程序:
1) 显示 'contacting server' 消息并显示旋转的进度条。
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 class '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";
}
}
这个错误是因为App只有在整个onClick完成后才会更新。这可以防止我需要的步骤 1) 发生。我是 Android 的新手,这对我提出了几个问题:
1) 为什么onClick在最后执行,不像传统的脚本语言是一行一行执行的?
2) 如果我在新线程中启动了 RequestServerTemp,为什么 MainActivity 会等待它完成?我觉得这对应用程序来说很糟糕,像这样的延迟是我们在新线程中启动网络的全部原因。
3) 几个与此类似的问题说 AsyncTask 是 'correct' 处理网络的方式,而不是 Runnable 或 Thread。是这样吗,我应该避免在 App 中使用 Runnable 和 Thread 吗?
我对问题3最感兴趣,因为很多Whosebug的答案都指向使用Runnable和Thread技术来完成网络,现在我在这里我担心我已经浪费了很多时间和精力。感谢阅读,欢迎为新的应用程序开发人员(或 Whosebug 用户!)提供任何一般提示和建议。
result = task.get();
get()
是一种阻塞方法。它一直等到 T
可用才能返回。这就是为什么 "MainActivity wait for it to finish".
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
提供委托,回调中的代码 onClick
在单击事件发生时执行。
我正在构建一个请求服务器温度的应用程序。按下按钮时,我希望应用程序:
1) 显示 'contacting server' 消息并显示旋转的进度条。
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 class '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";
}
}
这个错误是因为App只有在整个onClick完成后才会更新。这可以防止我需要的步骤 1) 发生。我是 Android 的新手,这对我提出了几个问题:
1) 为什么onClick在最后执行,不像传统的脚本语言是一行一行执行的?
2) 如果我在新线程中启动了 RequestServerTemp,为什么 MainActivity 会等待它完成?我觉得这对应用程序来说很糟糕,像这样的延迟是我们在新线程中启动网络的全部原因。
3) 几个与此类似的问题说 AsyncTask 是 'correct' 处理网络的方式,而不是 Runnable 或 Thread。是这样吗,我应该避免在 App 中使用 Runnable 和 Thread 吗?
我对问题3最感兴趣,因为很多Whosebug的答案都指向使用Runnable和Thread技术来完成网络,现在我在这里我担心我已经浪费了很多时间和精力。感谢阅读,欢迎为新的应用程序开发人员(或 Whosebug 用户!)提供任何一般提示和建议。
result = task.get();
get()
是一种阻塞方法。它一直等到 T
可用才能返回。这就是为什么 "MainActivity wait for it to finish".
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
提供委托,回调中的代码 onClick
在单击事件发生时执行。