にユーザーが戻るが、私は現在、私のサーバーにファイルをアップロードアプリに取り組んでいたとき。私のアプリは、タスクが完了するまで使用され、開始されてするように設計されており、最後にファイルのアップロードには、ボタンを押すことにより開始され、アプリはそれがためにそこにあるものを使用されてきました。だから非常に線形なアプローチ:開始、使用するまで、ファイルのアップロード、終了まで。onResumeでSTART_STICKYサービスを停止する方法()activty
今、私はいくつかの理由のために1は最後までそれを使用しないことを決定した場合も、自分のサーバーにファイルを送信したいと思います。したがって、onStop()が呼び出されるとき。
は、いくつかの研究の後、私は)(STARTSERVICEで)onStop(に呼び出さ結合していないサービスと行くことにしました。そのサービス内には、アップロードが成功するまで(serverResponseCode == 200)実行されるwhileループがあり、失敗した試行のたびにスリープします。
ユーザーが停止したアプリケーションの使用を再開すると、onResume()を呼び出すと、別のアクティビティでアップロードボタンをクリックすると、ファイル転送がキャンセルされます。 したがって、私はonResume()でサービスを停止しようとすると、サービスが停止しているというトーストを受け取りますが、ログカットにまだ実行中であることがわかります。サーバーに接続してスリープしてみてください。私がこれまで試してみました何
:
1)で回答に示唆されたものを試してみました:
automatically start up a service when the application is closed
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正しく?
多くのおかげであなたの答えが助けられ、魅力的に働きました。私は「return START_NOT_STICKY;」を追加するだけでした。 stopSelf()の後に; if文では、アクティビティが見られてもサービスが再び開始されます。 – Savate
さらにもう1つ、onStartCommandとhandleMessageが呼び出されたときに詳しいことができるかどうか尋ねてください。 booleanのkeepRunningは、handleMessage()が開始される前にfalseに設定されているように見えるので、アップロードが始まらなくてもkeepRunningはwhileループの直前でtrueに設定されます。だから私の論理はそれが真実に上書きされるべきだと言います。しかし、それはとにかく、どのように動作しますか?アプリケーションの起動時にもサービスが開始され、サービスはサーバーへの接続も設定しますが、ファイルアップロードは行われません。運が正しければ教えてください。大いに感謝して – Savate
がバグを発見しました。アプリを起動すると、via onStop()[ホームスクリーンに行く]その後、設定 - >アプリケーション - >実行中のサービスを手動で停止すると、スレッドは殺されません(おそらくSTART_STICKYのためですが、私のアプリ/アクティビティに再開するとソリューションは消えてしまいます。これはちょっと不思議なことかもしれませんが、それはなぜですか? – Savate