【问题标题】:How to return Void function doInBackground in AsynTask?如何在 AsyncTask 中返回 Void 函数 doInBackground?
【发布时间】:2017-02-23 16:24:57
【问题描述】:

如何在asyntask中获取函数void的结果 我试过这样,但应用程序总是停止

我想在等待过程中用asyntask在webview中实现一个进度条

注意:我已阅读此Webview with asynctask on Android

public class MainActivity extends AppCompatActivity {

    EditText edInput;
    Button btnCari;
    WebView webView;
    public String dataUrl;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUI();
        initEvent();
        new asynCaller().execute();
    }


    private void initUI(){
        edInput = (EditText) findViewById(R.id.editText);
        dataUrl = edInput.getText().toString();
        btnCari = (Button) findViewById(R.id.button);
        webView = (WebView) findViewById(R.id.webview);
    }

    private void initEvent() {
        btnCari.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String dataUrl = edInput.getText().toString();
                dataUrl = dataUrl.isEmpty() ? "google" : dataUrl;
                loadWebview("https://" + dataUrl + ".com");
                message("Data link is "+dataUrl);
            }
        });
    }

    private void message(String pesan){
        Toast.makeText(MainActivity.this,pesan, LENGTH_SHORT).show();
    }

    private boolean checkConnection(){
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnectedOrConnecting();
    }

    private void statusConnection(){
        if (checkConnection()){
            message("Device Online");
        }else{
            message("Device Offline");
        }
    }

    private void loadWebview(String url){
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl(url);
        webView.getSettings().setBuiltInZoomControls(true);
        webView.getSettings().setSupportZoom(true);

    }

    public class asynCaller extends AsyncTask<Void, Void, Void> {
        ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
//            progressDialog.setMessage("Loading...");
//            progressDialog.show();
            message("persiapan");
        }

        @Override
        protected Void doInBackground(Void... params) {
            statusConnection();
            if (checkConnection()) {
                dataUrl = dataUrl.isEmpty() ? "google" : dataUrl;
                loadWebview("https://" + dataUrl + ".com");
                message("Data link is " + dataUrl);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
//            progressDialog.dismiss();
            message("selesai");
        }
    }

已编辑 感谢您的帮助 我将方法 doInBackground 更改为 onProgressUpdate 以显示 Webview 和工作,我在进度对话框中遇到了新问题,进度对话框无法关闭()

@Override
        protected String doInBackground(String... params) {
            publishProgress();
            return url;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            url = edInput.getText().toString();
            progressDialog.show(MainActivity.this,"Pesan","Memuat . . .",true);
        }

        @Override
        protected void onPostExecute(String result) {
            if (progressDialog.isShowing()){
                progressDialog.dismiss();
            }
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
            loadWeb(url);
        }
    }

【问题讨论】:

  • 设置asy任务的第三个参数为字符串。
  • 您无法从后台线程更新您的 UI。

标签: android android-asynctask return


【解决方案1】:

将您的 doInBackground() 返回类型更改为 String/int

   public class asynCaller extends AsyncTask<Void, Void, String> {
            ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
    //            progressDialog.setMessage("Loading...");
    //            progressDialog.show();
                message("persiapan");
            }

            @Override
            protected String doInBackground(String... params) {
                statusConnection();
                if (checkConnection()) {
                    dataUrl = dataUrl.isEmpty() ? "google" : dataUrl;
                    loadWebview("https://" + dataUrl + ".com");
                    message("Data link is " + dataUrl);
                }
                return "Your Message";
            }

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
    //            progressDialog.dismiss();
    Log.d("Reached_postExe",result);
                message("result");
            }
        }

【讨论】:

  • doInBackground 无法返回字符串
【解决方案2】:

以下是我将使用的代码,由您自己的代码重构而来。我冒昧地对您的消息进行了更改,以使其在控制台中更有意义。

   public class AsynCaller extends AsyncTask<Void, Void, String> {
    ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        System.out.println("AsynCaller.onPreExecute called");
        // progressDialog.setMessage("Loading...");
        // progressDialog.show();
        message("AsynCaller.onPreExecute called");
    }

    @Override
    protected String doInBackground(Void... params) {
        System.out.println("AsynCaller.doInBackground called");
        statusConnection();
        final String result; // making it final forces it's definition whichever logic flow the code takes, which is good practice for a returned value 
        if (checkConnection()) {
            dataUrl = dataUrl.isEmpty() ? "google" : dataUrl;
            final String fullUrl = "https://" + dataUrl + ".com";
            loadWebview(fullUrl);
            result = "AsynCaller.doInBackground loadWebView called with " + fullUrl;
        } else {
            result = "AsynCaller.doInBackground checkConnection() is false");
        }
        // message(result); this is unnecessary as the Toast will appear due to the message() call in onPostExecute
        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        System.out.println("AsynCaller.onPostExecute called");
        // progressDialog.dismiss();
        message(result);
    }
}

如果我是你,我会用 Log.d() 替换 System.out 调用,以便控制台输出仅在可调试模式下完成,而不是在应用程序的任何发布版本中完成。参考这里是Log

作为最后的建议,我不会让 ProgressDialog 成为 AsyncTask 的属性,而是调用 MainActivity 中的方法,就像你对 message() 所做的那样。例如,在这种情况下,如果一个对象有效地持有对 Activity 上下文的引用并且在对象继续存在时 Activity 被销毁,例如正在运行的 AsyncTask 的情况,则可能存在内存泄漏等问题。 /p>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    相关资源
    最近更新 更多