justdan0227
justdan0227

Reputation: 1362

Fragments and Threads in Android

I have a MainActivity that uses fragments.

The onCreate of MainActivity completes its onCreate with the use of

welcomeFragment = new MyWelcomeFragment();
fr.beginTransaction().replace(R.id.mainContent, welcomeFragment).commit() 

As a part of MyWelcomeFragment's on onResume, a thread is started to get updates from my webserver. If the user selects an action before the thread is completed and goes to MyNewsFragment, what happens to the thread that has yet to complete running in MyWelcomeFragment's thread stack?

Thread was created with: (myThread and handler are instance variables)

  myThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    sendDataToServer("");
                    handler = new Handler(Looper.getMainLooper());
                    handler.post(new Runnable() {
                        public void run() {
                            onTaskDone();
                        }
                    });
                }
            });
            myThread.start();

Upvotes: 5

Views: 7963

Answers (3)

inmyth
inmyth

Reputation: 9060

Dalvik keeps all Thread references in the runtime so your thread will keep running unless it is terminated or completes (some reference). So depending on where you start your thread, you may be creating more than one. There is no clean way to cancel a Thread and in this case you may need to first cancel the http request inside sendDataToServer and use a shared flag to stop the thread.

In a bigger picture, I would suggest

  • move the networking method to Activity and handle it there since it has longer lifespan than Fragment
  • use Android Volley to handle networking. With it you can manage inadvertent multiple requests to send data to your server. Since each request can be attached with tag, you can cancel any with a particular tag in the queue (in your case the one corresponding to sendDataToServer process) before starting a new one.
  • and finally use Publisher-Subsriber pattern which has already been made available by libraries like Otto or EventBus. This allows communication between Fragments or Activities while avoiding life cycle related problems. In a gist: a publisher emits events to subscribers registered to it and unlike listeners both publisher and subscriber are totally decoupled. In your case, when sendDataToServer completes, you will not know if the fragment containing onTaskDone is still around. If this method manipulates UI while the fragment has destroyed its view then you will definitely get an error. So onTaskDone should be wrapped inside a subscriber method whose parent fragment is registered to the http event publisher and deregistered as soon as its view is destroyed.

Upvotes: 2

Finn K
Finn K

Reputation: 620

It'll keep running until run() method completes, which is probably for how long it takes for sendDataToServer("") takes to complete, as the handler should be fairly quick in comparison to network IO - or the thread is force interrupted.

Are you still interested in the result if the user switches fragments?

Are you keeping a reference to the welcome fragment? (Via either fragment manager or activity) - if so you could still access the result.

If the user goes back to welcome fragment, the previous thread reference will be lost.

Upvotes: 1

Abhishek Bansal
Abhishek Bansal

Reputation: 5335

Thread will keep on running till MyWelcomeFragment is alive and If you don't kill it in onPause().

Upvotes: 0

Related Questions