如何在AsynTask中返回Void函数doInBackground?

时间:2016-10-14 09:31:57

标签: android android-asynctask return

如何在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");
        }
    }

EDITED 谢谢你的帮助 我将方法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);
        }
    }

2 个答案:

答案 0 :(得分: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");
            }
        }

答案 1 :(得分:0)

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

   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>