java - Android - 使用 Callable 进行联网

标签 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。是这样吗,我应该避免在 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/

相关文章:

java - Hashmap null 转换为 int

java - 按住按键时 Swing 中的文本输入字段在 OS X 上停止工作

android - Cordova WebView.loadUrl 在浏览器中打开外部链接

python - 每个连接都有单独的线程?

c# - monitor.wait 是否向其他线程发出信号

c# - 单机低延迟、高吞吐量数据传输的最佳并发框架

java - Spring Security 身份验证失败 : error org. hibernate.HibernateException:未找到当前线程的 session

java - 数组的 subList - 转换为通用类型时出现 ClassCastException

java - Android 设备提供不正确的 Displaymetrics

java - 从解析表中检索字符串值