1

私は最高のプログラマーではありません。実際、私はかなり悪いです :( 私を夢中にさせている何かについて助けが必要です。基本的に私は tcpdump プロセスを持っています。数ミリ秒、私はすべてを試しましたが、うまくいきません。

エラーは発生せず、バックグラウンドで動作しているように見えますが、ホーム画面に移動してアプリに戻った後にのみ、テキストのチャンクのみが表示されます. ただし、テキストビューを常に更新するわけではなく、ハングしたりクラッシュしたりすることがあります。

テキストビューをプレーンテキストで問題なく更新できる単純なハンドラーを作成しましたが、プロセスを読み取るために大きな問題に直面しました。

開始ボタン

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.capture);

    this.LiveTraffic = (TextView) findViewById(R.id.LiveTraffic);
    this.CaptureText = (TextView) findViewById(R.id.CaptureText);
    ((TextView) findViewById(R.id.ipv4)).setText(getLocalIpv4Address());
    ((TextView) findViewById(R.id.ipv6)).setText(getLocalIpv6Address());


    //Begin button              
    final Button startButton = (Button) findViewById(R.id.start);
    startButton.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            Toast.makeText(getApplicationContext(), "Now Capturing Packets", Toast.LENGTH_LONG).show();
            try {

                process = Runtime.getRuntime().exec("su");
                DataOutputStream os = new DataOutputStream(process.getOutputStream());
                os.writeBytes("/data/local/tcpdump -q\n");
                os.flush();
                os.writeBytes("exit\n");
                os.flush();
                os.close();

                inputStream = new DataInputStream(process.getInputStream());

                Thread.sleep(1000);
                Process process2 = Runtime.getRuntime().exec("ps tcpdump");

                DataInputStream in = new DataInputStream(process2.getInputStream());
                String temp = in.readLine();
                temp = in.readLine();
                temp = temp.replaceAll("^root *([0-9]*).*", "$1");
                pid = Integer.parseInt(temp);
                Log.e("MyTemp", "" + pid);
                process2.destroy();

                CaptureActivity.this.thisActivity.CaptureText.setText("Active");
            } catch (Exception e) {
            }
            ListenThread thread = new ListenThread(new BufferedReader(new InputStreamReader(inputStream)));
            thread.start();
        }
    });
}

ListenThread クラス

public class ListenThread extends Thread {

    public ListenThread(BufferedReader reader) {
        this.reader = reader;
    }
    private BufferedReader reader = null;

    @Override
    public void run() {

        reader = new BufferedReader(new InputStreamReader(inputStream));
        while (true) {
            try {
                CaptureActivity.this.thisActivity.CaptureText.setText("exec");
                int a = 1;
                String received = reader.readLine();
                while (a == 1) {
                    CaptureActivity.this.thisActivity.LiveTraffic.append(received);
                    CaptureActivity.this.thisActivity.LiveTraffic.append("\n");
                    received = reader.readLine();
                    CaptureActivity.this.thisActivity.CaptureText.setText("in loop");

                }
                CaptureActivity.this.thisActivity.CaptureText.setText("out loop");

            } catch (Exception e) {
                Log.e("FSE", "", e);
            }
        }
    }
}
4

1 に答える 1

1

私はAndroidの専門家ではありませんが、次のことに気づきました。

  • UIスレッドでI/O操作を実行しています。これによりI/O操作が終了するまでGUIがフリーズします==>別のスレッドで実行します。
  • のUIスレッドの外部からUIを更新すると、ListenThread予期しない結果が生じる可能性があります

このチュートリアルで詳細を読むことができます(最初の例は(意図的に)壊れているので、必ず2つの例を読んでください)。

編集
結論として、最初のコードには次のようなものが含まれているはずです。

startButton.setOnClickListener(new OnClickListener() {

    public void onClick(View v) {
        Toast.makeText(getApplicationContext(), "Now Capturing Packets", Toast.LENGTH_LONG).show();
        new Thread(new Runnable() {

            public void run() {
                try {

                    process = Runtime.getRuntime().exec("su");
                    ...
                    CaptureActivity.this.runOnUiThread(new Runnable() {
                        public void run() {
                            CaptureActivity.this.thisActivity.CaptureText.setText("Active");
                        }
                    });
                } catch (Exception e) {
                }
                ListenThread thread = new ListenThread(new BufferedReader(new InputStreamReader(inputStream)));
                thread.start();
            }
        }).start();
    }
});

そして2番目に:

   while (true) {
        try {
            CaptureActivity.this.runOnUiThread(new Runnable() {

                public void run() {
                    CaptureActivity.this.thisActivity.CaptureText.setText("exec");
                }
            });

            int a = 1;
            String received = reader.readLine();
            while (a == 1) {
                CaptureActivity.this.runOnUiThread(new Runnable() {

                    public void run() {
                        CaptureActivity.this.thisActivity.LiveTraffic.append(received);
                        CaptureActivity.this.thisActivity.LiveTraffic.append("\n");
                        CaptureActivity.this.thisActivity.CaptureText.setText("in loop");
                    }
                });
                received = reader.readLine();
            }
            CaptureActivity.this.runOnUiThread(new Runnable() {

                public void run() {
                    CaptureActivity.this.thisActivity.CaptureText.setText("out loop");
                }
            });

        } catch (Exception e) {
            Log.e("FSE", "", e);
        }
    }

これで、特定のUIインタラクションの問題が解決するはずです。しかし、コードにはこの質問を超える他の論理的な問題があります(たとえば、読んでいるファイルの終わりに到達したかどうかをテストしないという事実、while(a == 1)が無限ループであるという事実)などの値を変更することはないため)。

于 2012-06-28T10:22:26.967 に答える