Electric Coffee
Electric Coffee

Reputation: 12104

Fragmented AsyncTask WebView causing problems

I'm following

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

to get an idea as to how to use AsyncTask for my project, all goes well and all but there's just one minor issue; best practice for Android is to use fragments to handle all the GUI...

Using fragments wasn't so hard last time I tried doing it, so I thought I could just jump straight into it and follow the tutorial best I could...

Long story short, the program crashes every time I hit the button to load the WebView

Here's my Fragment:

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) {
        }
    }
}

And for the record; this is the error message I get:

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})

So can any of you tell me how to fix this? Without getting rid of the AsyncTask or the Fragment that is...

From the responses I got I conclude this: Find a better tutorial... Thanks guys!

Upvotes: 3

Views: 1736

Answers (2)

Raghunandan
Raghunandan

Reputation: 133560

Your are loading a url in webview in doInbackground. You should do on the ui thread.

You would use asynctask while doing some network related operation like getting data from server.

Pls move you webview code to onCreateView or onActivityCreated

Also there is no need for ArrayList<Button>. You just have 2 buttons

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;
    }

Upvotes: 2

CQM
CQM

Reputation: 44220

View objects cannot be loaded in an background thread, they must be accessed and modified in the UI thread.

The WebVIEW is a view object. Stop calling it in the AsyncTask's "doinBACKGROUND" thread

Upvotes: 0

Related Questions