无法停止后台服务android
Posted
技术标签:
【中文标题】无法停止后台服务android【英文标题】:Can't stop background service android 【发布时间】:2015-12-17 06:08:25 【问题描述】:我正在运行以下后台服务:
public class TranslationService extends IntentService implements ClipboardManager.OnPrimaryClipChangedListener
private Language mFrom;
private Language mTo;
private String mTranslation;
private ClipboardManager mClipboardManager;
public TranslationService()
super("hello");
public TranslationService(String name)
super(name);
@Override
protected void onHandleIntent(Intent intent)
@Override
public int onStartCommand(Intent intent, int flags, int startId)
mFrom = (Language) intent.getSerializableExtra(MainActivity.FROM_STRING);
mTo = (Language) intent.getSerializableExtra(MainActivity.TO_STRING);
mClipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
mClipboardManager.addPrimaryClipChangedListener(this);
return super.onStartCommand(intent, flags, startId);
@Override
public void onPrimaryClipChanged()
ClipData clip = mClipboardManager.getPrimaryClip();
String copiedText = clip.getItemAt(0).getText().toString();
connectToTranslationApi(copiedText);
//TODO solve concurrency problems if app works inconsistently.
try
Thread.sleep(500);
catch (InterruptedException e)
e.printStackTrace();
new Handler(Looper.getMainLooper()).post(new Runnable()
@Override
public void run()
Toast.makeText(getBaseContext(), mTranslation, Toast.LENGTH_SHORT).show();
);
private void connectToTranslationApi(String copiedPhrase)
String apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
String fromInitials = mFrom.initials;
String toInitials = mTo.initials;
String yandexUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate?key="+
apiKey + "&lang=" +
fromInitials + "-" + toInitials +
"&text="+ copiedPhrase;
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(yandexUrl).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback()
@Override
public void onFailure(Request request, IOException e)
//TODO handle failure
@Override
public void onResponse(Response response) throws IOException
if (response.isSuccessful())
String jsonData = response.body().string();
try mTranslation = getTextTranslation(jsonData);
catch (JSONException e) e.printStackTrace();
);
private String getTextTranslation(String jsonData) throws JSONException
JSONObject data = new JSONObject(jsonData);
String translation = data.getString("text");
translation = translation.replace("]", "")
.replace("[", "")
.replace("\"", "");
return translation;
该服务在后台运行并翻译我复制到剪贴板的文本(即使我使用其他应用程序。只有当我从 RAM 中删除启动它的应用程序时,该服务才会停止),这一切都很好。
但是,当我回到应用程序的主要活动并按“停止服务”时,它不会停止。这是启动(并应该停止)服务的代码
if(mIsServiceRunning == false)
Intent i = new Intent(MainActivity.this, TranslationService.class);
i.putExtra(FROM_STRING, mLanguageFrom);
i.putExtra(TO_STRING, mLanguageTo);
startService(i);
mIsServiceRunning = true;
startButton.setText("Stop Service");
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
else
Intent i = new Intent(MainActivity.this, TranslationService.class);
stopService(i);
mIsServiceRunning = false;
startButton.setText("Start Service");
任何想法如何阻止它?
【问题讨论】:
你怎么知道它没有停止? 【参考方案1】:我不完全确定您如何确定您的服务仍在运行。 但我建议不要基于 mIsServiceRunning 布尔值。
您可以使用此方法来确保它是否正在运行:
public static boolean isServiceRunning(Class<?> serviceClass)
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
if (serviceClass.getName().equals(service.service.getClassName()))
return true;
return false;
此方法将返回一个布尔值,告诉您服务是否在后台运行, 例如,您可以像这样使用它:
if (isServiceRunning(TranslationService.class))
Toast.makeText(this, "Service is Running", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "Service is NOT Running", Toast.LENGTH_SHORT).show();
也许我也错过了它,但我在您的代码中看不到任何错误。
context.stopService(new Intent(context, TranslationService.class));
应该停止你的服务。
希望对您有所帮助,如果没有,请尝试在您尝试后提供更多信息。
【讨论】:
好吧,每次我复制到剪贴板时仍然会弹出一个翻译,这样做的方法是在服务的类中,所以我看不出它怎么可能没有运行。顺便说一句,在您建议的代码中,在 WorkoutApplication.getInstance() 我应该用什么替换 WorkoutApplication? 抱歉,我会编辑一下,WorkoutApplication.getInstance() 是上下文。【参考方案2】:存在内存泄漏,因为您在未销毁剪贴板方法的情况下离开了它。 在特定活动被破坏后,您需要从 ram 中创建清除剪贴板对象的侦听器。尽管服务已停止,但此剪贴板方法在内存中运行。您需要通过此代码停止
clipboardManager.removePrimaryClipChangedListener(listener);
在任何 onDestroy(),onPause() 方法上。
试着理解下面的代码
public class MySecretService extends Service
ClipboardManager clipboardManager;
ClipData clipData;
ClipData.Item item;
String text;
//declare Listener
ClipboardManager.OnPrimaryClipChangedListener listener;
@Nullable
@Override
public IBinder onBind(Intent intent)
return null;
@Override
public void onCreate()
Toast.makeText(this, "Service is Started !!!", Toast.LENGTH_SHORT).show();
clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
@Override
public int onStartCommand(Intent intent, int flags, int startId)
Toast.makeText(this, "Service is Created !!! ", Toast.LENGTH_SHORT).show();
//fire intent
intent = new Intent(MySecretService.this, DictionaryActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final Intent finalIntent = intent;
//asign listener to onPrimaryClipChangedListner
clipboardManager.addPrimaryClipChangedListener(listener = new ClipboardManager.OnPrimaryClipChangedListener()
@Override
public void onPrimaryClipChanged()
clipData = clipboardManager.getPrimaryClip();
item = clipData.getItemAt(0);
try
text = item.getText().toString();
catch (NullPointerException e)
Toast.makeText(MySecretService.this, "exception " + e, Toast.LENGTH_SHORT).show();
Toast.makeText(MySecretService.this, "Text is Copiyed " + text, Toast.LENGTH_SHORT).show();
//startActivity when copy triggered on text
startActivity(finalIntent);
);
return super.onStartCommand(intent, flags, startId);
@Override
public void onDestroy()
super.onDestroy();
// DictionaryActivity.finishAll();
Toast.makeText(this, "Service is Destroyed !!! ", Toast.LENGTH_SHORT).show();
//free from memroy
clipboardManager.removePrimaryClipChangedListener(listener);
【讨论】:
【参考方案3】:我正在做同样的事情,我注意到只要应用程序缓存在内存中,服务就会运行。我将尝试在服务中添加 if else 语句以检查首选项/设置,以便即使服务正在运行或缓存,它也会检查共享首选项并决定继续或停止。 (保持它检查它是否关闭是不好的,但我想不出别的东西
【讨论】:
【参考方案4】:您需要从要停止它的位置调用 stopservice(intent) 方法并覆盖服务类中的 onDestroy(),现在 stopservice() 将调用服务类的 destroy 方法现在您可以放置代码以断开正在进行的进程onDestroy().
经过这么多努力,我得到了结果!希望你能回答!
【讨论】:
以上是关于无法停止后台服务android的主要内容,如果未能解决你的问题,请参考以下文章