0

我正在编写一个运行无限 ping 的应用程序,使用系统命令 /system/bin/ping 来测量网络状态。

为了处理正在运行的线程,我使用了 Fragment。因此在屏幕旋转或屏幕锁定期间该进程仍在运行。当我按下返回按钮或主页按钮时,该应用程序似乎运行良好。但是当我用最近的应用程序杀死应用程序时,即使主应用程序关闭,线程仍在运行。

当然,我可以使用 -c 选项限制 ping 的数量,但我想在应用程序关闭后立即停止线程。

有没有办法知道一个应用程序使用最近的应用程序被杀死?

我应该使用 Fragment / AsyncTask 以外的其他方式来处理这种类型的线程吗?

谢谢您的帮助

主类:

public class MainActivity extends Activity implements PingFragment.PingTaskCallbacks {

    /* Fragment used to manage the ping task*/
    private PingFragment mPingFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm = getFragmentManager();
        mPingFragment = (PingFragment) fm.findFragmentByTag("ping");

        // If the Fragment is non-null, then it is currently being
        // retained across a configuration change.
        if (mPingFragment == null) {
            mPingFragment = new PingFragment();
            fm.beginTransaction().add(mPingFragment, "ping").commit();
        }//endIf

        ...
    }//endFct

    @Override
    protected void onResume() {
        super.onResume();
    }//endFct

    @Override
    protected void onPause() {
        super.onPause();
    }//endFct

    public void doPing() {

        String url = "www.google.com";
        mPingFragment.startPing(url);
    }

    public void stopPing() {

        mPingFragment.stopPing();
    }

    @Override
    public void onProgressUpdate(String aPingLine) {

        // method called on every ping
    }
}

片段类:

public class PingFragment extends Fragment {

    /**
     * Callback interface through which the fragment will report the
     * task's progress and results back to the Activity.
     */
    static interface PingTaskCallbacks {
        void onProgressUpdate(String aPingLine);
    }//endIntf

    private PingTaskCallbacks mCallbacks;
    private PingTask mTask;

    /**
     * This method will only be called once when the retained
     * Fragment is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Retain this fragment across configuration changes.
        setRetainInstance(true);
    }

    /**
     * Hold a reference to the parent Activity so we can report the
     * task's current progress and results. The Android framework
     * will pass us a reference to the newly created Activity after
     * each configuration change.
     */
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mCallbacks = (PingTaskCallbacks) activity;
    }

    /**
     * Set the callback to null so we don't accidentally leak the
     * Activity instance.
     */
    @Override
    public void onDetach() {
        super.onDetach();
        mCallbacks = null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("PingFragment.onDestroy()", "*** Fragment call destroy ***");
        stopPing();
    }

    public void startPing(String url) {
        if (mTask != null && ! mTask.getStatus().equals(AsyncTask.Status.FINISHED)) {
            mTask.stop();
        }//endIf

        // Create and execute the background task.
        mTask = new PingTask();
        mTask.execute(url);
    }

    public void stopPing() {
        mTask.stop();
        mTask = null;
    }

    /**
     * A task that performs some ping in background.
     *
     * Note that we need to check if the callbacks are null in each
     * method in case they are invoked after the Activity's and
     * Fragment's onDestroy() method have been called.
     */
    private class PingTask extends AsyncTask<String, String, Void> {

        private PipedOutputStream mPOut;
        private PipedInputStream mPIn;
        private LineNumberReader mReader;
        private Process mProcess;

        @Override
        protected void onPreExecute() {

            mPOut = new PipedOutputStream();
            try {
                mPIn = new PipedInputStream(mPOut);
                mReader = new LineNumberReader(new InputStreamReader(mPIn));
            } catch (IOException e) {
                cancel(true);
            }//endTry
        }//endF

        /**
         * Note that we do NOT call the callback object's methods
         * directly from the background thread, as this could result
         * in a race condition.
         */
        @Override
        protected Void doInBackground(String... params) {

            String aLine = "";

            try {
                mProcess = new ProcessBuilder()
                        .command("/system/bin/ping", params[0])
                        .redirectErrorStream(true)
                        .start();

                try {
                    InputStream in = mProcess.getInputStream();
                    OutputStream out = mProcess.getOutputStream();
                    byte[] buffer = new byte[1024];
                    int count;

                    // in -> buffer -> mPOut -> mReader -> 1 line of ping information to parse
                    while ((count = in.read(buffer)) != -1) {
                        mPOut.write(buffer, 0, count);

                        while (mReader.ready()) {
                            aLine = mReader.readLine();
                            publishProgress(aLine);
                        }//endWhile

                        if (isCancelled()) {
                            stop();
                            break;
                        }//endIf

                    }//endWhile

                    out.close();
                    in.close();
                    mPOut.close();
                    mPIn.close();
                } finally {
                    stop();
                }//endTry
            } catch (IOException e) {
            }//endTry

            return null;
        }//endFct

        @Override
        protected void onProgressUpdate(String... aPingLine) {
            if (mCallbacks != null) {
                mCallbacks.onProgressUpdate(aPingLine[0]);
            }//endIf
        }//endFct

        public void stop() {
            if (mProcess != null) {
                mProcess.destroy();
                mProcess = null;
            }//endIf

            cancel(true);
        }//endStop
    }
}
4

3 回答 3

0

请覆盖中的onPostExecute方法PingTask

于 2013-11-04T10:05:53.053 回答
0

当活动被破坏时,您必须停止Ping。

http://developer.android.com/reference/android/app/Activity.html

你也要做

mTask=null ;
于 2013-11-04T09:56:50.637 回答
0

检查这个链接,它可能对你有帮助,

http://developer.android.com/reference/android/os/AsyncTask.html#isCancelled%28%29

检查该方法并将其写在您的代码中:

if( isCancelled ()){
break;
}
于 2013-11-04T10:06:12.090 回答