조각의 runOnUiThread


121

활동을 조각으로 변환하려고합니다. 의 오류 표시 runOnUiThread. 과거에 :

GoogleActivityV2는 활동에서 확장됩니다. ExecuteTask 클래스의 runOnUiThread. 활동에 중첩 된 ExecuteTask 클래스.

(확인 실행) 지금 :

GoogleActivityV2는 Fragment에서 확장됩니다. ExecuteTask 클래스의 runOnUiThread. 활동에 중첩 된 ExecuteTask 클래스. (runOnUiThread 오류)

여기 내 코드입니다

public class GoogleActivityV2 extends SherlockMapFragment implements OnMapClickListener , OnMapLongClickListener , OnCameraChangeListener , TextWatcher {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View rootView = inflater.inflate(R.layout.activity_googlev2, container, false);
        Init();
        adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_dropdown_item_1line);
        textView = (AutoCompleteTextView) getView().findViewById(R.id.autoCompleteTextView1);
        return rootView;
    }

    public void onCameraChange(CameraPosition arg0){
        // TODO Auto-generated method stub
    }

    public void onMapLongClick(LatLng arg0){
        llLoc = arg0;
        stCommand = "onTouchEvent";
        lp = new ExecuteTask();
        lp.execute();
    }

    public void onMapClick(LatLng arg0){
        // TODO Auto-generated method stub
    }

    class ExecuteTask extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            if(stCommand.compareTo("AutoCompleteTextView") != 0) {
                pDialog = new ProgressDialog(getActivity());
                pDialog.setMessage(Html.fromHtml("<b>Search</b><br/>Loading ..."));
                pDialog.setIndeterminate(false);
                pDialog.setCancelable(false);
                pDialog.show();
            }
        }

        protected String doInBackground(String ... args){
            do something
            return null;
        }

        @Override
        protected void onPostExecute(String file_url){
            if(stCommand.compareTo("AutoCompleteTextView") != 0) pDialog.dismiss();
            runOnUiThread(new Runnable() {
                public void run(){
                    do something
                }
            });
        }
    }
    public void afterTextChanged(Editable s){
        // TODO Auto-generated method stub
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after){
        // TODO Auto-generated method stub
    }

    public void onTextChanged(CharSequence s, int start, int before, int count){
        // TODO Auto-generated method stub
    }
}

오류 내용 : Eclipse 오류

이 오류를 어떻게 해결할 수 있습니까?


8
onPostExecute 내부에 작성한 코드는 이미 주 스레드 내부에서 실행됩니다. 반면에 runOnUiThread ()를 호출 할 필요가 없습니다.
— rciovati

@rciovati "무엇인가"onPostExecute는 다릅니다
— Tai Dao

답변:


271

이 시도: getActivity().runOnUiThread(new Runnable...

왜냐하면:

1) this호출 의 암시 는 runOnUiThread조각이 아닌 AsyncTask를 참조하는 것입니다.

2) FragmentrunOnUiThread가 없습니다.

그러나 Activity그렇습니다.

참고 Activity단지를 실행 Runnable하면 메인 쓰레드에 이미 있다면, 그렇지 않으면 그것은을 사용합니다 Handler. 의 컨텍스트에 대해 걱정하지 않으려면 조각에서 를 구현할 수 있습니다.Handlerthis 실제로 매우 쉽습니다.

// A class instance
private Handler mHandler = new Handler(Looper.getMainLooper());

// anywhere else in your code
mHandler.post(<your runnable>);
// ^ this will always be run on the next run loop on the main thread.

편집 : @rciovati가 맞습니다, 당신은 onPostExecute이미 주 스레드에 있습니다.


3
때때로 getActivity (). runOnUiThread가 NullPointerException을 발생시킵니다. 설명해 주시겠습니까?
— developer1011

1
@ developer1011은 조각이 활동에서 분리되었을 때 발생합니다. 이것은 비동기 작업에서 일반적입니다 get. 항상 null을 먼저 확인하십시오.
— bclymer

4
감사. 나는 둘러싸여 getActivity().runOnUiThread와 함께 if (isAdded())하고 그것을 잘 작동합니다
— developer1011을

1
이 답변이 주어진 @bclymer는 조각의 UI 스레드에 대한 Google의 사실상 참조이며 마지막 섹션 (동일한 작업을 수행하는 핸들러를 구현하는 방법)에 대한 자세한 내용은 좋을 것입니다!
— LS97

4

Xamarin.Android에서

조각의 경우 :

this.Activity.RunOnUiThread(() => { yourtextbox.Text="Hello"; });

활동 :

RunOnUiThread(() => { yourtextbox.Text="Hello"; });

해피 코딩 :-)


4

Kotlin 확장 기능 사용

fun Fragment?.runOnUiThread(action: () -> Unit) {
    this ?: return
    if (!isAdded) return // Fragment not attached to an Activity
    activity?.runOnUiThread(action)
}

그런 다음, 어떤에서 Fragment당신은 단지 호출 할 수 있습니다 runOnUiThread. 이렇게하면 활동과 조각에서 일관된 호출이 유지됩니다.

runOnUiThread {
    // Call your code here
}

참고 : Fragment가 더 이상에 연결되지 않으면 Activity콜백이 호출되지 않고 예외가 발생하지 않습니다.

어디에서나이 스타일에 액세스하려면 공통 객체를 추가하고 메서드를 가져올 수 있습니다.

object ThreadUtil {
    private val handler = Handler(Looper.getMainLooper())

    fun runOnUiThread(action: () -> Unit) {
        if (Looper.myLooper() != Looper.getMainLooper()) {
            handler.post(action)
        } else {
            action.invoke()
        }
    }
}

1
나는 kotlin 확장 기능을 절대적으로 좋아합니다.
— OhhhThatVarun

2

조각에서 날짜와 시간을 가져 오는 데 이것을 사용했습니다.

private Handler mHandler = new Handler(Looper.getMainLooper());
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    View root = inflater.inflate(R.layout.fragment_head_screen, container, false);

    dateTextView =  root.findViewById(R.id.dateView);
    hourTv = root.findViewById(R.id.hourView);

        Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                while (!isInterrupted()) {
                    Thread.sleep(1000);
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            //Calendario para obtener fecha & hora
                            Date currentTime = Calendar.getInstance().getTime();
                            SimpleDateFormat date_sdf = new SimpleDateFormat("dd/MM/yyyy");
                            SimpleDateFormat hour_sdf = new SimpleDateFormat("HH:mm a");

                            String currentDate = date_sdf.format(currentTime);
                            String currentHour = hour_sdf.format(currentTime);

                            dateTextView.setText(currentDate);
                            hourTv.setText(currentHour);
                        }
                    });
                }
            } catch (InterruptedException e) {
                Log.v("InterruptedException", e.getMessage());
            }
        }
    };
}

1

다른 스레드의보기를 사용하여 실행 가능 파일을 게시 할 수도 있습니다. 그러나 뷰가 null이 아닌지 확인하십시오.

 tView.post(new Runnable() {
                    @Override
                    public void run() {
                        tView.setText("Success");
                    }
                });

문서에 따르면 :

"boolean post (Runnable action) Runnable이 메시지 큐에 추가되도록합니다. runnable은 사용자 인터페이스 스레드에서 실행됩니다."

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.