2016-05-10 6 views
1

にユーザーが戻るが、私は現在、私のサーバーにファイルをアップロードアプリに取り組んでいたとき。私のアプリは、タスクが完了するまで使用され、開始されてするように設計されており、最後にファイルのアップロードには、ボタンを押すことにより開始され、アプリはそれがためにそこにあるものを使用されてきました。だから非常に線形なアプローチ:開始、使用するまで、ファイルのアップロード、終了まで。onResumeでSTART_STICKYサービスを停止する方法()activty

今、私はいくつかの理由のために1は最後までそれを使用しないことを決定した場合も、自分のサーバーにファイルを送信したいと思います。したがって、onStop()が呼び出されるとき。

は、いくつかの研究の後、私は)(STARTSERVICEで)onStop(に呼び出さ結合していないサービスと行くことにしました。そのサービス内には、アップロードが成功するまで(serverResponseCode == 200)実行されるwhileループがあり、失敗した試行のたびにスリープします。

ユーザーが停止したアプリケーションの使用を再開すると、onResume()を呼び出すと、別のアクティビティでアップロードボタンをクリックすると、ファイル転送がキャンセルされます。 したがって、私はonResume()でサービスを停止しようとすると、サービスが停止しているというトーストを受け取りますが、ログカットにまだ実行中であることがわかります。サーバーに接続してスリープしてみてください。私がこれまで試してみました何

1)で回答に示唆されたものを試してみました:

automatically start up a service when the application is closed

stop service in android

2)onStartCommandはSTART_NOT_STICKYを返す場合でも、それが起こります。

HERE MY CODE:

サービスコード:開始を呼び出し、サービスを停止し

import android.app.Service; 
import android.content.Intent; 
import android.os.Handler; 
import android.os.HandlerThread; 
import android.os.IBinder; 
import android.os.Looper; 
import android.os.Message; 
import android.os.Process; 
import android.support.annotation.Nullable; 
import android.util.Log; 
import android.widget.Toast; 

import java.io.DataOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 

public class UploadService extends Service { 
    private Looper mServiceLooper; 
    private ServiceHandler mServiceHandler; 
    private static final String TAG = "UploadService"; 

    int serverResponseCode = 0; 

    String upLoadServerUri = null; 
    String uploadFilePath; 
    String uploadFileName; 

    // Handler that receives messages from the thread 
    private final class ServiceHandler extends Handler { 
     public ServiceHandler(Looper looper) { 
      super(looper); 
     } 

     @Override 
     public void handleMessage(Message msg) { 

      //... have some Server connection parameters here 

      while (serverResponseCode != 200) { 

       // ... trying to upload a file to my server 

       if (serverResponseCode != 200) { 
        try { 
         Log.d(TAG, "Thread slepps"); 
         Thread.sleep(10000); 

        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 

      stopSelf(msg.arg1); 
     } 
    } 


    private class DisplayToast implements Runnable { 
     String mText; 

     public DisplayToast(String text) { 
      mText = text; 
     } 

     public void run() { 
      Toast.makeText(UploadService.this, mText, Toast.LENGTH_SHORT).show(); 
     } 
    } 


    @Override 
    public void onCreate() { 
     // Start up the thread running the service. Note that we create a 
     // separate thread because the service normally runs in the process's 
     // main thread, which we don't want to block. We also make it 
     // background priority so CPU-intensive work will not disrupt our UI. 
     HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); 
     thread.start(); 

     // Get the HandlerThread's Looper and use it for our Handler 
     mServiceLooper = thread.getLooper(); 
     mServiceHandler = new ServiceHandler(mServiceLooper); 
    } 


    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); 
     // For each start request, send a message to start a job and deliver the 
     // start ID so we know which request we're stopping when we finish the job 
     Message msg = mServiceHandler.obtainMessage(); 
     msg.arg1 = startId; 
     mServiceHandler.sendMessage(msg); 

     // If we get killed, after returning from here, restart 
     return START_STICKY; 
    } 


    @Override 
    public void onDestroy() { 
     Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); 

    } 

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

} 

活動:

import android.app.Activity; 
import android.app.Dialog; 
import android.content.Context; 
import android.content.Intent; 
import android.graphics.Color; 
import android.graphics.Point; 
import android.graphics.PorterDuff; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.LayerDrawable; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.PopupMenu; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.Window; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.PopupWindow; 
import android.widget.RatingBar; 
import android.widget.TextView; 
import android.widget.Toast; 
import android.widget.SearchView; 
import android.widget.SearchView.OnQueryTextListener; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

public class AppSelectionActivity extends AppCompatActivity implements View.OnClickListener, OnQueryTextListener { 

    private final static String TAG = "AppSelectionActivity"; 
    private boolean leftOnIntent = false; // is set to true when starting one of my other activity with an intent, so that service will not be started 
    private Intent serviceIntent; 

    @Override 
    protected void onStop() { 
     Log.d(TAG,"onStop: app is stopped"); 
     if (!leftOnIntent) { 
      serviceIntent = new Intent(AppSelectionActivity.this, UploadService.class); 
      startService(serviceIntent); 
      Log.d(TAG, "onStop: Intent is started"); 
     } 
     super.onStop(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     Log.d(TAG,"onResume: app is resumed"); 
     stopService(new Intent(AppSelectionActivity.this, UploadService.class)); 
     leftOnIntent = false; 
    } 

    @Override 
    protected void onDestroy() { 
     Log.d(TAG,"onDestroy: got called"); 
     super.onDestroy(); 
    } 
} 

サービスを停止する方法任意の提案やファイルuploade正しく?

答えて

0

あなたHandlerあなたがアップロードループ(while (serverResponseCode != 200))を停止するように設定することができますいくつかのフラグを必要とします。

keepRunning = true; 
while (serverResponseCode != 200 && keepRunning) 
{ 
     // ... trying to upload a file to my server 
     if (serverResponseCode != 200) { 
      try { 
       Log.d(TAG, "Thread slepps"); 
       Thread.sleep(10000); 

      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
} 

を、あなたのServiceを停止したい場合は、あなたが今、あるIntentアクションでstartService()を呼び出すことによって、そうすることができます...

:それでは、次のようにループを修正し

public boolean keepRunning; 

をご紹介しましょうあなたはその後、onStartCommand()に評価

Intent intent = new Intent(this, UploadService.class); 
intent.setAction("your.package.name.STOP_UPLOAD"); 
startService(intent); 

...。

String intentAction = (intent != null) ? intent.getAction() : ""; 
if ("your.package.name.STOP_UPLOAD".equals(intentAction)) 
{ 
    mServiceHandler.keepRunning = false; 
    stopSelf(); 
} 
else 
{ 
    Message msg = mServiceHandler.obtainMessage(); 
    msg.arg1 = startId; 
    mServiceHandler.sendMessage(msg); 
} 
return START_STICKY; 

あなたのコード内の特定の他のメソッドが実行されている場合、ランタイムによって呼び出され、ここで関与していくつかの方法があります。

  • Service.onStartCommand()startService()
  • Handler.handleMessage()によってトリガーされるがsendMessage();
  • によってトリガされます

あなたのケースでは、handleMessage()が実行時afによって呼び出されますあなたはmServiceHandler.sendMessage(msg);と呼んでいます。これにより、ユーザーがActivityに戻ったときにビジー状態になるアップロードが開始され、onResume()がトリガーされます。この方法では、startService()を呼び出してアップロードを中止します。

これにより、onStartCommand()がトリガーされます。 Intentアクションを評価した後、booleanはfalseに設定されます。 Handlerはまだループを実行している可能性があります。whileこのような場合、条件はもはや真ではないため、ループは今停止します。

+0

多くのおかげであなたの答えが助けられ、魅力的に働きました。私は「return START_NOT_STICKY;」を追加するだけでした。 stopSelf()の後に; if文では、アクティビティが見られてもサービスが再び開始されます。 – Savate

+0

さらにもう1つ、onStartCommandとhandleMessageが呼び出されたときに詳しいことができるかどうか尋ねてください。 booleanのkeepRunningは、handleMessage()が開始される前にfalseに設定されているように見えるので、アップロードが始まらなくてもkeepRunningはwhileループの直前でtrueに設定されます。だから私の論理はそれが真実に上書きされるべきだと言います。しかし、それはとにかく、どのように動作しますか?アプリケーションの起動時にもサービスが開始され、サービスはサーバーへの接続も設定しますが、ファイルアップロードは行われません。運が正しければ教えてください。大いに感謝して – Savate

+0

がバグを発見しました。アプリを起動すると、via onStop()[ホームスクリーンに行く]その後、設定 - >アプリケーション - >実行中のサービスを手動で停止すると、スレッドは殺されません(おそらくSTART_STICKYのためですが、私のアプリ/アクティビティに再開するとソリューションは消えてしまいます。これはちょっと不思議なことかもしれませんが、それはなぜですか? – Savate

関連する問題