片段中的runOnUiThread

Tai*_*Dao 106 android android-fragments android-activity

我正在尝试将Activity转换为片段.错误标记打开runOnUiThread.在过去:

GoogleActivityV2从Activity扩展而来.类ExecuteTask中的runOnUiThread.class ExecuteTask嵌套在activity上.

(运行确定)现在:

GoogleActivityV2从Fragment扩展而来.类ExecuteTask中的runOnUiThread.class ExecuteTask嵌套在activity上.(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
    }
}
Run Code Online (Sandbox Code Playgroud)

错误说: Eclipse错误

我该如何解决这个错误?

bcl*_*mer 246

试试这个: getActivity().runOnUiThread(new Runnable...

这是因为:

1)this你的调用中隐含的runOnUiThread是指AsyncTask,而不是你的片段.

2)Fragment没有runOnUiThread.

但是,Activity确实如此.

请注意,如果您已经在主线程上,则Activity执行Runnable,否则使用a Handler.如果您不想担心上下文,可以Handler在片段中实现一个this,它实际上非常简单:

// 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.
Run Code Online (Sandbox Code Playgroud)

编辑:@rciovati是对的,你在onPostExecute,它已经在主线程上了.

  • 谢谢.我用```if(isAdded())```包围```getActivity().runOnUiThread```它工作正常 (4认同)
  • 有时候getActivity().runOnUiThread导致NullPointerException.你能解释一下吗? (3认同)
  • @developer1011 当片段与活动分离时会发生这种情况。这在异步任务中很常见,因为活动可能在长时间运行的操作过程中被销毁,因此它不再存在于“get”中。始终首先检查是否为空。 (2认同)

pat*_*val 9

对于片段上的 Kotlin,只需执行此操作

activity?.runOnUiThread(Runnable {
        //on main thread
    })
Run Code Online (Sandbox Code Playgroud)


Gib*_*olt 8

使用 Kotlin 扩展函数

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

然后,在任何Fragment你可以调用runOnUiThread. 这使活动和片段之间的调用保持一致。

runOnUiThread {
    // Call your code here
}
Run Code Online (Sandbox Code Playgroud)

注意:如果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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我非常喜欢 kotlin 扩展函数。 (4认同)