0

I am downloading and updating data when app starts.And if connection fails,i am using timer for retry.

My code:

void listConversations() {
    Ion.with(context, "url")
    .asJsonArray()
    .setCallback(new FutureCallback<JsonArray>() {
        @Override
        public void onCompleted(Exception e, final JsonArray result) {
            if (e == null) {
                    new Thread(new Runnable() {
                        public void run() {
                            for (int i=1; i<result.size(); i++) {
                                JsonObject newData=result.get(i).getAsJsonObject();
                                _db.updateConversation(newData);
                            }
                            ((ConversationsAdapter) conversationsAdapter).updateConversations(conversationsList);
                        }
                    }).start();
            }else{
                new Timer().schedule(new TimerTask() {          
                    @Override
                    public void run() {
                        listConversations();      
                    }
                }, 10000);
            }
        }
    });

}

If connection is successful,my code is working great.But if connection fails,this method calling every 10 seconds.Then if connects successful after retry,my app is crashing with following log:

02-02 00:30:55.682: E/AndroidRuntime(21820): FATAL EXCEPTION: Thread-642
02-02 00:30:55.682: E/AndroidRuntime(21820): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
02-02 00:30:55.682: E/AndroidRuntime(21820):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5908)
02-02 00:30:55.682: E/AndroidRuntime(21820):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:837)
02-02 00:30:55.682: E/AndroidRuntime(21820):    at android.view.View.requestLayout(View.java:15792)
02-02 00:30:55.682: E/AndroidRuntime(21820):    at android.view.View.requestLayout(View.java:15792)
02-02 00:30:55.682: E/AndroidRuntime(21820):    at android.view.View.requestLayout(View.java:15792)
02-02 00:30:55.682: E/AndroidRuntime(21820):    at android.view.View.requestLayout(View.java:15792)
02-02 00:30:55.682: E/AndroidRuntime(21820):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:358)

I guess it is trying access ui from another thread.How can I resolve this ? I need to do db operations in another thread.

Okan
  • 1,379
  • 3
  • 25
  • 38

1 Answers1

0

You are right you are trying to manipulate view's from a thread they don't belong to. You should use handler for this type of task.

Create a handler like this

Handler h = new Handler(){
    @Override
    public void handleMessage(Message msg){
        if(msg.what == 0){
            listConversations();
        }
    }
};

and change the else part of your code like this

new Timer().schedule(new TimerTask() {          
    @Override
    public void run() {
        h.sendEmptyMessage(0);      
    }
}, 10000);
Rohit5k2
  • 17,948
  • 8
  • 45
  • 57
  • I will try the code.But why i should use handler for this ? Can you explain ? i want to learn. – Okan Feb 02 '15 at 00:55
  • Answer of this question explains it very nicely. You might wana read this http://stackoverflow.com/questions/12312926/why-use-handler – Rohit5k2 Feb 02 '15 at 00:59
  • Oh sorry i haven't see – Okan Feb 02 '15 at 01:02
  • Last question: why it is working well if connection doesn't fail at first time ? – Okan Feb 02 '15 at 01:04
  • Thing is if you call the part of if statement in else then it would work. You are calling the complete method in else which is part of ui thread. In else you have timer and in if statement you have runnable. They are different. – Rohit5k2 Feb 02 '15 at 01:08