当片段被销毁时杀死后台线程

艾哈迈德·阿卜杜·埃尔梅格德

我有一个片段,它有一个后台线程,当我尝试在同一活动中启动另一个片段时,它会更新进度条值并在进度值达到某个值时更改可绘制的进度条,以防出现此错误

    E/UncaughtException: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.support.v4.app.FragmentActivity.getResources()' on a null object reference
    at com.example.mego.adas.ui.CarFragment$PotProgressThread$1.run(CarFragment.java:831)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:7409)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.mego.adas, PID: 25935
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.support.v4.app.FragmentActivity.getResources()' on a null object reference
    at com.example.mego.adas.ui.CarFragment$PotProgressThread$1.run(CarFragment.java:831)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:7409)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

这是线程的代码

    class PotProgressThread implements Runnable {

    @Override
    public void run() {
        while (potSensorValue <= 1025 && fragmentIsRunning) {

            if (fragmentIsRunning) {

                // Update the progress bar
                potProgressBarHandler.post(new Runnable() {
                    public void run() {
                        potProgressBar.setProgress((int) potSensorValue);
                        if (potSensorValue >= 800) {
                            potProgressBar.setProgressDrawable(getActivity().
                                    getResources().getDrawable(R.drawable.progressbarred));
                        } else {
                            potProgressBar.setProgressDrawable(getActivity().
                                    getResources().getDrawable(R.drawable.progressbarblue));

                        }
                    }
                });
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }
}

在这里,我在 onCreateView() 方法中开始我的线程

   @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {


    View rootView = inflater.inflate(R.layout.fragment_car, container, false);
    initializeScreen(rootView);

    //check the internet connection
     connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
     networkInfo = connectivityManager.getActiveNetworkInfo();

    if (networkInfo != null && networkInfo.isConnected()) {
        buildGoogleApiClient();

        //set up the firebase
        mFirebaseDatabase = FirebaseDatabase.getInstance();

        //get the references for the childes
        //the main child for the directions services
        carDatabaseReference = mFirebaseDatabase.getReference().child(constant.FIREBASE_CAR);

        //the childes for the direction root
        connectionStateDatabaseReference = mFirebaseDatabase.getReference()
                .child(constant.FIREBASE_CAR).child(constant.FIREBASE_CONNECTION_STATE);

        accidentStateDatabaseReference = mFirebaseDatabase.getReference()
                .child(constant.FIREBASE_CAR).child(constant.FIREBASE_ACCIDENT_STATE);

        startStateStateDatabaseReference = mFirebaseDatabase.getReference()
                .child(constant.FIREBASE_CAR).child(constant.FIREBASE_START_STATE);

        lightsStateDatabaseReference = mFirebaseDatabase.getReference()
                .child(constant.FIREBASE_CAR).child(constant.FIREBASE_LIGHTS_STATE);

        lockStateDatabaseReference = mFirebaseDatabase.getReference()
                .child(constant.FIREBASE_CAR).child(constant.FIREBASE_LOCK_STATE);

        mappingServicesDatabaseReference = mFirebaseDatabase.getReference()
                .child(constant.FIREBASE_CAR).child(constant.FIREBASE_MAPPING_SERVICES);

        sensorsValuesDatabaseReference = mFirebaseDatabase.getReference()
                .child(constant.FIREBASE_CAR).child(constant.FIREBASE_SENSORES_VALUES);

        connectionStateDatabaseReference.setValue(1);


    }
    //show Snackbar if there is no internet net connection
    else {
        if (carFragment != null) {

            //   Snackbar snackbar = Snackbar.make(carFragment, R.string.no_internet_connection, Snackbar.LENGTH_LONG);
            // snackbar.show();
        }
    }

    //get the date from the connected thread
    bluetoothHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            //if message is what we want
            if (msg.what == handlerState) {
                // msg.arg1 = bytes from connect thread
                String readMessage = (String) msg.obj;

                //keep appending to string until ~ char
                recDataString.append(readMessage);

                //determine the end of the line
                endOfLineIndex = recDataString.indexOf("~");
                if (fragmentIsRunning) {
                    refreshUI();
                }

            }
        }
    };

    //setup ans start the threads
    potThread = new Thread(new PotProgressThread());
    tempThread = new Thread(new TemperatureProgressThread());
    ldrThread = new Thread(new LdrProgressThread());


    fragmentIsRunning = true;
    potThread.start();
    tempThread.start();
    ldrThread.start();


    //set the buttons listener
    lightsButton.setOnClickListener(this);
    lockButton.setOnClickListener(this);
    disconnectButton.setOnClickListener(this);
    startButton.setOnClickListener(this);

    //setup the map fragment
    MapFragment mapFragment = (MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.my_location_fragment_car);
    mapFragment.getMapAsync(this);

    // Inflate the layout for this fragment
    return rootView;
}

这是 onDestoryview() 方法的代码

fragmentIsRunning = false;
potThread.interrupt();

我怎么能杀死它

沙利什

Dalvik 将所有线程引用保留在运行时中,因此您的线程将继续运行,除非它终止或完成(一些引用)。因此,根据您开始线程的位置,您可能会创建多个线程。

在您的情况下,您的线程执行未完成并且您更改了片段,因此您的内容getActivity()将为空。

解决方法是 before getActivity(),检查是否isAdded()为真,如果不为真,则表示片段已经分离,调用getActivity()将返回空值。

记住在线程中,在调用之前的任何地方getActivity(),您最好再次检查 isAdded(),因为在线程执行期间用户可能随时退出活动。

其他解决方案

我不确定,但您可以通过Context全局初始化和线程中的上下文来实现

Context mContext;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
{
     mContext = getActivity();
     ....
}

现在在您的线程中使用此上下文。

class PotProgressThread implements Runnable {

    @Override
    public void run() {
        while (potSensorValue <= 1025 && fragmentIsRunning) {

            if (fragmentIsRunning) {

                // Update the progress bar
                potProgressBarHandler.post(new Runnable() {
                    public void run() {
                        potProgressBar.setProgress((int) potSensorValue);
                        if (potSensorValue >= 800) {
                            potProgressBar.setProgressDrawable(mContext.
                                    getResources().getDrawable(R.drawable.progressbarred));
                        } else {
                            potProgressBar.setProgressDrawable(mContext.
                                    getResources().getDrawable(R.drawable.progressbarblue));

                        }
                    }
                });
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }
}

我希望你能得到解决方案。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章