【问题标题】:Tips with AsyncTask cleanup and usage AndroidAsyncTask 清理和使用 Android 的技巧
【发布时间】:2012-05-10 21:03:22
【问题描述】:

这是我第一次使用 AsyncTask,它可以工作,但它很脏,因为我只是复制并粘贴了一些代码。我想以正确的方式并尽可能干净。那么任何人都可以帮助我清理我的代码并告诉我如何以正确的方式去做吗?你会帮我一个很大的忙,帮助我,让我在未来的 Android 开发中获得更多经验。我想从一开始就以正确的方式学习它;)

编辑: 在阅读了一堆教程并观看了视频之后,我认为我取得了巨大的进步!我很高兴我做到了!但是只剩下一个小问题了。在应用程序启动时,它不会加载页面。在我单击一个链接后,shouldOverrideUrlLoading 效果很好,但在启动时它只显示一个空白屏幕。有什么问题?

public class WebviewActivity extends MainActivity {

    private WebView myWebView;
    private ProgressDialog progressDialog;
    private boolean mConnection = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final ScrollView mainScrollView = (ScrollView)findViewById(R.id.ScrollView01);

        myWebView = (WebView)findViewById(R.id.webview);
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        myWebView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                new checkConnection().execute();
                if (mConnection == true){
                    view.loadUrl(url);
                }           
                return true;                
            }
            @Override
            public void onPageFinished(WebView view, String url) {
                mainScrollView.fullScroll(ScrollView.FOCUS_UP);
            }
        });

        myWebView.requestFocus(View.FOCUS_DOWN);
        myWebView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                    case MotionEvent.ACTION_UP:
                        if (!v.hasFocus()) {
                            v.requestFocus();
                        }
                        break;
                }
                return false;
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();       
        new checkConnection().execute();
        if (mConnection == true){
            myWebView.loadUrl(webLink);
        }
    }

    //------------------------------------------------------
    //-----DOING THE CONNECTION CHECK IN ANOTHER THREAD-----
    //------------------------------------------------------

    public class checkConnection extends AsyncTask<Void, Void, Void>{

        int mStatusCode = 0;
        Exception mConnectionException;

        @Override
        protected void onPreExecute(){
            super.onPreExecute();           
            progressDialog = ProgressDialog.show(WebviewActivity.this, "", "Loading...", true);
            progressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            try {
                ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

                if (cm.getActiveNetworkInfo().isConnectedOrConnecting()) {
                    URL url = new URL(webLink);
                    HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
                    urlc.setConnectTimeout(1000 * 5); // mTimeout is in seconds
                    urlc.connect();

                    mStatusCode = urlc.getResponseCode();

                    if (mStatusCode == 200){
                        //Nothing to do.
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                mConnectionException = e;
            }
            return null;
        }   

        @Override
        protected void onPostExecute(Void param){
            progressDialog.dismiss();

            if (mStatusCode  == 200){
                mConnection = true;
            }
            else if (mStatusCode  == 404){
                myWebView.loadUrl("file:///android_asset/errorpage404.html");
            }
            else {
                myWebView.loadUrl("file:///android_asset/errorpage.html");
            }
        }
    }
}

【问题讨论】:

    标签: android performance webview android-asynctask


    【解决方案1】:

    请不要从doInBackground() 调用progressDialog.dismiss();,而是使用onPostExecute()doInBackground() 不是 UI 线程,因此尝试操纵 UI 元素可能会给您带来严重的后果。

    这就是您在第一次尝试时没有加载页面的原因:

            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                new checkConnection().execute();  <- (1)
                if (mConnection == true){         <- (2)
                    view.loadUrl(url);
                }           
                return true;                
    

    (1) 启动异步任务,该任务将在未来某个时间完成 (2) 尝试检查(1) 立即的结果,所以还没有结果。


    这是您的AsyncTask 的修改版本,它接受 url 作为参数:

    public class checkConnection extends AsyncTask<String, Void, String>{     <------ change this
    
        int mStatusCode = 0;
        Exception mConnectionException;
    
        @Override
        protected void onPreExecute(){
            super.onPreExecute();           
            progressDialog = ProgressDialog.show(WebviewActivity.this, "", "Loading...", true);
            progressDialog.show();
        }
    
        @Override
        protected Void doInBackground(String... params) {     <------ change this
            try {
                ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    
                if (cm.getActiveNetworkInfo().isConnectedOrConnecting()) {
                    URL url = new URL(webLink);
                    HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
                    urlc.setConnectTimeout(1000 * 5); // mTimeout is in seconds
                    urlc.connect();
    
                    mStatusCode = urlc.getResponseCode();
    
                    if (mStatusCode == 200){
                        //Nothing to do.
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                mConnectionException = e;
            }
            return params[0];     <------ change this
        }   
    
        @Override
        protected void onPostExecute(String param){     <------ change this
            progressDialog.dismiss();
    
            if (mStatusCode  == 200){
                myWebView.loadUrl(param);     <------ change this
            }
            else if (mStatusCode  == 404){
                myWebView.loadUrl("file:///android_asset/errorpage404.html");
            }
            else {
                myWebView.loadUrl("file:///android_asset/errorpage.html");
            }
        }
    }
    

    【讨论】:

    • 谢谢,我想我现在已经取得了很大的进步。检查我的主要帖子。我现在唯一的问题是它在第一次启动时没有加载页面。你明白为什么吗?
    • 嗯,很清楚。但是如何检查 (1) 是否完成?
    • 您不必检查。将view.loadUrl() 移动到AsyncTask,以便在您检查网站可用后立即加载。而且,顺便说一句,检查您是否使用setRequestMethod() 指定HEAD 方法而不是默认的GET 方法会更快,后者会检索整个页面。
    • 而您的onResume() 版本也存在与上述相同的问题,请不要忘记也修复它。
    • 享受 Android 开发的乐趣! =)
    猜你喜欢
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 2016-01-04
    相关资源
    最近更新 更多