Use Observer in Fragment

android, fragment, observable, observer-pattern

Solution

In Android, you can only manipulate `View`s from the UI thread. You can run some code on the UI thread by using `View.post()`, like this:

@Override
public void update(java.util.Observable o, final Object arg) {
    this.post(new Runnable() {
        public void run() {
            this.setText(String.valueOf(arg));
        } 
    }
}

http://developer.android.com/reference/android/view/View.html#post(java.lang.Runnable)

Problem

I've a problem when using an observer in a fragment, I've implemented my own TextViewObserver, and I wan't to insert it in a Fragment: ``` public class TextViewObserver extends TextView implements Observer { public TextViewObserver(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public TextViewObserver(Context context, AttributeSet attrs) { super(context, attrs); } public TextViewObserver(Context context) { super(context); } @Override public void update(java.util.Observable o, Object arg) { // TODO Auto-generated method stub this.setText(String.valueOf(arg)); } ``` My fragment code: ``` public class MyFragment extends Fragment { private TextViewObserver mTextView;// = new TextView(this.getActivity()); private ApplicationContext mContext; private DataObservable mDataObservable; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_6, container, false); mTextView = (TextViewObserver) view.findViewById(R.id.sicthtxtview); return view; } @Override public void onAttach(Activity activity) { super.onAttach(activity); mContext = (ApplicationContext) activity.getApplicationContext(); mDataObservable = mContext.getObservable(); } @Override public void onStart() { super.onStart(); mDataObservable.addObserver(mTextView); } ``` My DataObservable is in my class ApplicationContext (extending Application): ``` public class ApplicationContext extends Application { private DataObservable _mData; @Override public void onCreate() { super.onCreate(); _mData = new DataObservable(); } public DataObservable getObservable() { return _mData; } ``` MyTextViewObserver have to be notified when the DataObservable change, and in result setText in the Fragment. This is the error given by the LogCat: ``` android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. ``` Thx

Original source