Canberk
Canberk

Reputation: 435

Data passing from a separate asynctask to a fragment

I have a separate asynctask class which creates a url for me. I tried to use an interface in the onPostExecute to send the url to my fragment, but could not managed it. I was always doing the same process in the fragments by forcing to implement the interface in onAttach.

After myTask.execute(), i simply wait for the result with a progress dialog on the screen. Everything works fine until the interface's callback method is called.(nullpointerexception)

How can I force the fragment to make it implement the interface? (I need to send the data directly to the fragment, not via activity)

Thank you very much for your time.

Upvotes: 1

Views: 2683

Answers (2)

Canberk
Canberk

Reputation: 435

Alright I found my mistake finally. As ePeace mentioned in his answer. In my Asyntask class, I created a constructor which throws nullpointerexception is the listener is null.

AsyncListener listener;
public ReportFactory(AsyncListener a)
{
    if(a == null)
    {
        throw new NullPointerException("Listener cant be null");
    }

    this.setListener(a);
}

public interface AsyncListener {
    public void onComplete(String url);
}


public void setListener(AsyncListener listener) {
    this.listener = listener;
}

After that, in the fragment class, I created a listener. (Have a global reference in the class to the listener, so that you can use it on the other places in the fragment lifecycle)

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

  listener = new AsyncListener()
{

    @Override
    public void onComplete(String url)
    {
        URL = url;          
        webview.loadUrl(URL);         
    }
};      
}

And finally, in the onCreate method I created my Asyntask and gave the listener as a paramater.

ReportFactory factory = new ReportFactory(listener);
factory.execute(usr, designFile);     

Hope it works for you who might need it later. Thank you very much for your time ePeace.

Upvotes: 0

ePeace
ePeace

Reputation: 1997

You could try making a interface and have a method or a constructor in your asynctask that accepts said listener.

Create the listener in your fragment and set it for you asynctask.

public class Example extends AsyncTask<Void, Void, Void> {
AsyncListener listener;
Object result;

@Override
protected Void doInBackground(Void... params) {
    return null;
}

@Override
protected void onPostExecute(Void result) {
    this.result = result;
    super.onPostExecute(result);
    if(listener != null)
        listener.onComplete(result);
}

public void setListener(AsyncListener listener) {
    this.listener = listener;
}

public Object getResult() {
    return result;
}

public interface AsyncListener {
    public void onComplete(Object object);
}
}

public class ExampleFragment extends Fragment implements AsyncListener {
private Example task;

public static ExampleFragment newInstance(Example task) {
    this.task = task;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Object object;
    if((object = task.getResult()) == null)
        task.setListener(listener);
    else
        onComplete(object);

    return super.onCreateView(inflater, container, savedInstanceState);
}

public void onComplete(Object object) {

}
}

Upvotes: 2

Related Questions