Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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();
like image 938
justdan0227 Avatar asked Oct 19 '22 13:10

justdan0227


1 Answers

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.
like image 129
inmyth Avatar answered Oct 22 '22 02:10

inmyth