2

押すとサービスを開始するボタンがあります。このサービスは、デバイスからの情報のログ記録を開始します。ただし、実行を押すと、ログが記録されている間、画面が約 8 秒間一時的にフリーズし、終了すると画面のフリーズが解除され、トースト メッセージが表示されます (ボタンを押すとすぐに表示されるはずです)。何でもできます。アプリケーションがログを記録しているときにアプリケーション画面に再度アクセスすると (注: サービスは常に実行されているため、フリーズせず、ログのみが記録されます)、アクティビティは再びフリーズし、ログが完了するまで何もできません。

asynctasks を試し、新しい実行可能/新しいスレッドで実行しましたが、どれもうまくいかないようです。それらを正しく実装しているかどうかはわかりませんが、問題を修正したいと思います。

サービス クラスの onStartCommand は次のとおりです。

    @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // THIS WOULD BE THE METHOD THAT RUNS WHATEVER YOU WANT TO DO EVERY SO OFTEN SO FOR ME THIS IS GETTING ALL DATA ETC
    getProcessInfo();

    //  LOG DELAY = SECONDS BETWEEN RUNNING SERVICE/METHOD. SET AT THE TOP
    myPendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    Alarmmgr.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+LOG_DELAY*1000, myPendingIntent);
    Intent notificationIntent = new Intent(this, LogOrCheck.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this,
            101, notificationIntent,
            PendingIntent.FLAG_NO_CREATE);

    NotificationManager nm = (NotificationManager) this
            .getSystemService(Context.NOTIFICATION_SERVICE);

    Resources res = this.getResources();
    Notification.Builder builder = new Notification.Builder(this);

    builder.setContentIntent(contentIntent)
                .setSmallIcon(R.drawable.arrow_up_float)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.arrow_down_float))
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(true)
                .setContentTitle("Androigenius")
                .setContentText("Service running OK");
    Notification n = builder.getNotification();


    startForeground(100, n);
    return Service.START_STICKY;
}

そして、ここで startService を呼び出します。

but1.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            if (isClicked) {
                Context context = getApplicationContext();
                Toast toast = Toast.makeText(context, "Please press 'MINIMIZE' at the top to continue logging.", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.TOP|Gravity.RIGHT, 10, 55);
                toast.show();
                System.out.println("Start logging");
                but1.setText("Stop Logging");
                but1.setTextColor(Color.RED);
                // START SERVICE, DONE. (STOP IS BELOW).
                startService(myIntent);
                isClicked = false;
            } 
            else if (!isClicked) {
                System.out.println("Stop Logging");
                but1.setText("Start Logging");
                // STOP SERVICE, DONE.
                stopService(myIntent);
                but1.setTextColor(getResources().getColor(color.cornblue));
                isClicked = true;
            }
4

2 に答える 2

1

サービスはUIスレッドで実行されるため、「フリーズ」が発生します。IntentServiceを使用すると、UIスレッドではなく、バックグラウンドで自動的に実行されるサービスが作成されます。IntentServiceクラスの詳細は次のとおりです。

IntentServiceクラス

于 2013-02-14T15:42:41.563 に答える
0

デフォルトでは、サービスはアプリケーションのメインスレッドでも実行され、そこでUI操作が行われます。したがって、onStartCommand()メソッドで長いタスクを実行すると、メインスレッドがブロックされます。

この問題を回避するには、ロギングタスクを別のスレッドに移行する必要があります。AsycTaskクラスを使用してこれを行うことができます。クラスの使用方法については、 http://developer.android.com/reference/android/os/AsyncTask.htmlを参照してください。

于 2013-02-14T15:29:30.793 に答える