조각의 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.