碎片化的AsyncTask WebView导致问题

时间:2014-01-10 16:25:50

标签: android android-fragments webview android-asynctask

我正在关注

http://examples.javacodegeeks.com/android/core/os/asynctask/android-asynctask-example/

要了解如何为我的项目使用AsyncTask,一切顺利,但只有一个小问题; Android的最佳实践是使用片段来处理所有GUI ......

上次我尝试使用碎片并不是那么难,所以我想我可以直接跳到它并尽可能地遵循教程......

长话短说,每次按下按钮加载WebView时程序都会崩溃

这是我的片段:

package com.wausoft.app;

import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.Toast;

import java.net.URL;
import java.util.ArrayList;

public class MainFragment extends Fragment {

    protected ArrayList<Button> buttons = new ArrayList<Button>();

    protected View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            switch(view.getId()) {
                case R.id.btn_dummy:
                    dummyFunc(view);
                    break;
                case R.id.btn_load:
                    readWebpage();
                    break;
            }
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);
        buttons.add((Button) view.findViewById(R.id.btn_load));
        buttons.add((Button) view.findViewById(R.id.btn_dummy));

        for(Button btn : buttons) btn.setOnClickListener(listener);

        return view;
    }

    public void dummyFunc(View view) {
        Toast.makeText(view.getContext(), "Button Clicked", Toast.LENGTH_SHORT).show();
    }

    public void readWebpage() {
        try {
        URL url = new URL("http://www.example.com/");
        LoadWebpageAsync task = new LoadWebpageAsync();
        task.execute(url);
        } catch(Exception e) {
            Log.v("DEBUG: ", e.getMessage());
        }
    }

    private class LoadWebpageAsync extends AsyncTask<URL, Void, String> {
        @Override
        protected String doInBackground(URL... urls) {
            try {
            WebView webView = (WebView) getView().findViewById(R.id.web_view);
            webView.getSettings().setJavaScriptEnabled(true); // program crashes here
            webView.loadUrl(urls[0].toString());
            } catch (Exception e) {
                Log.v("DEBUG: ", e.getMessage());
            }

            return null;
        }

        @Override
        protected void onPostExecute(String s) {
        }
    }
}

记录;这是我收到的错误消息:

01-10 17:09:52.544  23959-24282/? V/DEBUG:﹕ java.lang.Throwable: A WebView method was called on thread 'AsyncTask #1'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {41e2e8d8} called on null, FYI main Looper is Looper (main, tid 1) {41e2e8d8})

你们中的任何人都可以告诉我如何解决这个问题吗?没有摆脱AsyncTask或片段......

从我得到的回复中我得出结论找一个更好的教程...... 谢谢你们!

2 个答案:

答案 0 :(得分:2)

您正在doInbackground的网页浏览中加载网址。你应该在ui线程上做。

您可以在执行与网络相关的操作时使用asynctask,例如从服务器获取数据。

请将您的网络视图代码移至onCreateViewonActivityCreated

此外,不需要ArrayList<Button>。你只有2个按钮

Button b1,b2; 
WebView wb;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);
        b1= (Button) view.findViewById(R.id.btn_load);
        b2=(Button) view.findViewById(R.id.btn_dummy);

        b1.setOnClickListener(listener);
        b2.setOnClickListener(listener);

        wb= (WebView) view.findViewById(R.id.web_view);
        wb.getSettings().setJavaScriptEnabled(true); 
        wb.loadUrl("http://www.example.com/"); 

        return view;
    }

答案 1 :(得分:0)

无法在后台线程中加载视图对象,必须在UI线程中访问和修改它们。

WebVIEW是一个视图对象。停止在AsyncTask的“doinBACKGROUND”线程中调用它