2017-05-05 1 views
0

여기서부터 내가 Activity.Once에서 서비스를 시작했는데 서비스가 시작되었습니다. on 명령 커맨드()에서 Notification Manger를 사용하여 지연된 Thread on Notification 패널을 사용하여 진행률 표시 줄을 업데이트하는 것입니다. 그러나 무슨 문제가 있습니다. 서비스의 destroy() 서비스가 호출 될 때보 다 서비스가 중지되고 진행률 막대 업데이트가 중지됩니다. 이 알림 관리자 .cancel All() 또는 스레드. 현재 스레드() .Service의 Destroy()에서 interrupt()를하지만 진행 바는 알림 패널에서 업데이트를 중지하지 않습니다. 모든 가능한 해결책을 시도했지만 스레드가 멈추지 않거나 진행 표시 줄이 알림 패널에서 계속 업데이트되는 것을 멈추지 않습니다. 멈추는 방법을 계속 표시합니다. 알림 패널에서 업데이트 할 때 진행률 표시 줄까지 수행 한 내용은 다음과 같습니다. .감사.백그라운드에서 알림 패널에 표시되는 진행률 표시 줄 업데이트를 중지하는 방법 서비스의 Destroy()가 호출 될 때의 서비스

MainActivity.java

public class MainActivity extends AppCompatActivity { 

    Button start, stop; 


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


     start = (Button) findViewById(R.id.start); 
     stop = (Button) findViewById(R.id.stop); 


     start.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 


       startService(new Intent(MainActivity.this, NotificationService.class)); 
      } 
     }); 

     stop.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 


       stopService(new Intent(MainActivity.this, NotificationService.class)); 


      } 
     }); 


    } 

} 

NotificationService.java

public class NotificationService extends Service { 

    private Thread thread; 
    private NotificationManager mNotifyManager; 
    private Builder mBuilder; 


    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     mNotifyManager = (NotificationManager) getSystemService(getApplicationContext().NOTIFICATION_SERVICE); 
     mBuilder = new NotificationCompat.Builder(NotificationService.this); 


     Toast.makeText(getApplicationContext(), "oncreate of service called", Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     super.onStartCommand(intent, flags, startId); 

     Toast.makeText(getApplicationContext(), "onStart of service called", Toast.LENGTH_SHORT).show(); 


     mBuilder.setContentTitle("Download") 
       .setContentText("Download in progress") 
       .setSmallIcon(R.mipmap.ic_launcher); 


     mBuilder.setProgress(100, 0, false); 
     mNotifyManager.notify(0, mBuilder.build()); 


     updateService(); 

     return START_NOT_STICKY; 


    } 

    private void updateService() { 

     thread = new Thread() { 
      @Override 
      public void run() { 


       for (int i = 0; i <= 100; i += 5) { 
        // Sets the progress indicator completion percentage 

        try { 


         mBuilder.setProgress(100, i, false); 
         mNotifyManager.notify(0, mBuilder.build()); 

         // Sleep for 5 seconds 
         Thread.sleep(2 * 1000); 

        } catch (InterruptedException e) { 
         Log.d("TAG", "sleep failure"); 
        } 


       } 


       mBuilder.setContentText("Download complete"); 
       // Removes the progress bar 
       mBuilder.setProgress(0, 0, false); 
       mNotifyManager.notify(0, mBuilder.build()); 


      } 
     }; 

     thread.start(); 


    } 


    @Override 
    public void onDestroy() { 
     super.onDestroy(); 


     Toast.makeText(getApplicationContext(), "service Destroyed", Toast.LENGTH_SHORT).show(); 


     // mNotifyManager.cancelAll(); 
     //mNotifyManager.cancel(0); 
     thread.currentThread().interrupt(); 

     // mNotifyManager.cancel(0); 

     // mNotifyManager.notify(0, mBuilder.build()); 


    } 
} 

답변

0

Thread.interrupt()는 즉시 스레드를 중단하지 않는다. 스레드의 인터럽트 상태 만 업데이트합니다. 스레드가 인터럽트 상태 (즉, 슬립)를 폴링하는 메소드를 포함하는 경우 스레드는 인터럽트된다. 그렇지 않으면 스레드는 단순히 실행을 완료하고 인터럽트 상태는 무시된다.

따라서, 귀하의 경우에는 당신이 다음을 수행 방법 :

private class MyWorkerThread extends Thread { 

    public MyWorkerThread(String name) { 
     super(name); 
    } 

    private boolean isStopThread = false; 

    public void setStopThread(boolean isStopThread) { 
     this.isStopThread = isStopThread; 
    } 


    @Override 
    public void run() { 
     super.run(); 

     for (int i = 0; i <= 100; i += 5) { 
      // Sets the progress indicator completion percentage 

      try { 

       if (mWorkerThread.isStopThread) { 
        Log.d("Thread", "thread is interrupted , so breaking loop !"); 
        mWorkerThread.interrupt(); 
        mWorkerThread = null; 
        break; 
       } 

       mBuilder.setProgress(100, i, false); 
       mNotifyManager.notify(0, mBuilder.build()); 

       // Sleep for 5 seconds 
       Thread.sleep(2 * 1000); 

      } catch (InterruptedException e) { 
       Log.d("TAG", "sleep failure"); 
      } 


     } 


     mBuilder.setContentText("Download complete"); 
     // Removes the progress bar 
     mBuilder.setProgress(0, 0, false); 
     mNotifyManager.notify(0, mBuilder.build()); 

    } 
} 

UpdateService 방법 :

private void updateService() { 

     mWorkerThread = new MyWorkerThread("MyWorkerThread"); 
     mWorkerThread.start(); 

    } 

들의 OnDestroy() 메소드

@Override public void onDestroy() { super.onDestroy(); Toast.makeText(getApplicationContext(), "service Destroyed", Toast.LENGTH_SHORT).show(); // mNotifyManager.cancelAll(); //mNotifyManager.cancel(0); //Setting flag for stop thread mWorkerThread.setStopThread(true); // mNotifyManager.cancel(0); // mNotifyManager.notify(0, mBuilder.build()); } 

가 당신을 도울 희망 !

+0

감사합니다. 나는이 플래그를 true 또는 false로 알고 루프에서 휴식을 취한다. 그러나 mNotifyManager.cancelAll() 메서드를 사용하여 알림 패널의 진행 표시 줄을 막는 방법은 NotificationManager에서 사용할 수 있습니다.이 메서드를 사용하면 progressbar의 업데이트가 중지되거나 트릭 만 사용됩니다. 나를 보여줄 수있다 – Viral

+0

@Viral mNotifyManager.cancellAll()이 완벽하게 작동하고 once.but 스레드가 다시 실행되도록 알림이 생성되도록 업데이트를 중지합니다. –

+0

@Viral 당신의 코드를 검사했다면, 알림이 취소되고 루프가 깨지면 루프 안에 bool 변수를 추가 할 수 있습니다. –