0

I'm trying to implement a callback method to be called whenever a Thread is is done It's work. I'm using the interface approach and not the Handler approach.

I have a main UI Thread which is the onCreate(Bundle) method and a Thread i call from within the onCreate(Bundle) method.

(Only relevant code posted).

MainActivity.java:

public class MainActivity extends AppCompatActivity implements GetDataFromTheWebThreadCallback
{
    public static GetDataFromTheWebThread getDataFromTheWebThread;
    private GetDataFromTheWebEventNotifier eventNotifier;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.eventNotifier = new GetDataFromTheWebEventNotifier(MainActivity.this);

        // The thread that will search the web for data
        this.getDataFromTheWebThread = new GetDataFromTheWebThread();
        getDataFromTheWebThread.start();
     }

        @Override
        public void finishParsing() // The callback method that never called
        {
            Toast.makeText(MainActivity.this,"Callback Method Called",Toast.LENGTH_LONG).show();
            Log.d("Callback:", "Callback Method Called");
        }
}

GetDataFromTheWebEventNotifier.java:

public class GetDataFromTheWebEventNotifier
{
    private GetDataFromTheWebThreadCallback callbackInterface;

    public GetDataFromTheWebEventNotifier(GetDataFromTheWebThreadCallback callbackInterface)
    {
        this.callbackInterface = callbackInterface;
    }

    public void onEvent()
    {
            this.callbackInterface.finishParsing();
    }
}

GetDataFromTheWebThreadCallback.java:

public interface GetDataFromTheWebThreadCallback
{
    void finishParsing(); // The method i wish to invoke when certain event will happen
}

GetDataFromTheWebThread.java:

public class GetDataFromTheWebThread extends Thread
{
    public static boolean isFinished = false; // False - the thread is still running. True - the thread is dead

    @Override
    public void run()
    {
        GetDataFromTheWebThread.isFinished = false;
        try
        {
            // Some internet computations...
            Thread.sleep(100);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        GetDataFromTheWebThread.isFinished = true;
    }
}

So what's wrong with my callback?

God
  • 1,238
  • 2
  • 18
  • 45

3 Answers3

1

You never call onEvent(). Is your notifier supposed to be watching the isFinished variable or something?

Don Kirkby
  • 53,582
  • 27
  • 205
  • 286
  • Because i want to call `onEvent()` if the `Thread` is finished AKA `GetDataFromTheWebThread.isFinished = true;` – God Apr 17 '16 at 14:33
  • `Is your notifier supposed to be watching the isFinished variable or something?` I don't know. I just want him to call `onEvent()` which will call the `callback` method whenever the `Thread` is "dead". – God Apr 17 '16 at 14:46
1

As for your ThreadClass, have a constructor with the callback :

public class GetDataFromTheWebThread extends Thread {
    public static boolean isFinished = false; // False - the thread is still running. True - the thread is dead
    private GetDataFromTheWebThreadCallback mCallback;

    public GetDataFromTheWebThread(GetDataFromTheWebThreadCallback c) {
      mCallback = c;
    }

    @Override
    public void run() {
      GetDataFromTheWebThread.isFinished = false;
      try {
        // Some internet computations...
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      GetDataFromTheWebThread.isFinished = true;
      if (mCallback !- null) {
        mCallback.finishParsing();
      }
    }
}

As for your Activity, simply pass the callback when creating your Thread :

this.getDataFromTheWebThread = new GetDataFromTheWebThread(this);

As well as :

    @Override
    public void finishParsing()  {
      // You know that this function is called from a background Thread.
      // Therefore from here, run what you have to do on the UI Thread
      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          Toast.makeText(MainActivity.this,"Callback Method Called",Toast.LENGTH_LONG).show();
          Log.d("Callback:", "Callback Method Called");
        }});

    }
NSimon
  • 5,212
  • 2
  • 22
  • 36
  • But that way It's not really a `callback`. I want to check if `GetDataFromTheWebThread.isFinished = true;` on the `onEvent()` method and not to call the `callback` when i know i `Thread` has done. Oh and it give `RuntimeException: Can't create handler inside thread that has not called Looper.prepare()` – God Apr 17 '16 at 14:42
  • @God What do you mean it's not really a callback? A callback is meant to call a special piece of code once an event occurs, such as the thread finishes in your case. – NSimon Apr 17 '16 at 14:47
  • Well, It's still generates a `RunTimeException` – God Apr 17 '16 at 14:49
  • as for the exception, see my Edit (runOnUIThread()) which will force the callback call to be run from the UIThread, thus prevent your RunTimeException – NSimon Apr 17 '16 at 14:59
  • Or i could just use `Looper.prepare();` at the start of `run()` method! – God Apr 17 '16 at 15:04
  • And `runOnUiThread` is not recognizable in my `Thread` `run()` scoop. So correct you'r answer to either `Looper.prepare()` or to pass the `Avtivity` as a parameter to the `Thread`. – God Apr 17 '16 at 15:06
0

Actually you didn't call onEvent(). And check AsyncTask.

Maxim G
  • 1,479
  • 1
  • 15
  • 23
  • Already tried. Didn't went well. http://stackoverflow.com/questions/36520737/asynctask-onpostexecute-is-never-called-w-art-suspending-all-threads-took. And where to cal `onEvent()`? – God Apr 17 '16 at 14:40