无法停止后台服务android

时间:2015-09-20 13:38:07

标签: java android android-intent android-service

我正在运行以下后台服务:

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");
        }

任何想法如何阻止它?

3 个答案:

答案 0 :(得分:0)

存在内存泄漏,因为您离开了剪贴板方法而没有破坏它。 在特定活动被破坏后,你需要从ram中获取清除剪贴板对象的监听器。尽管服务已停止,但此剪贴板方法在内存中运行。您需要停止此代码

  

clipboardManager.removePrimaryClipChangedListener(受听者);

对任何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);

}}

答案 1 :(得分:0)

我正在做同样的事情,我注意到只要应用程序缓存在内存中,服务就会运行。我将尝试在服务中添加if else语句以检查首选项/设置,以便即使运行或缓存它的服务也将检查共享首选项并决定继续或停止。 (保持检查它是否关闭但是我无法想象别的东西是不好的

答案 2 :(得分:0)

您需要从要停止它的地方调用 stopservice(intent) 方法并覆盖服务类中的 onDestroy(),现在 stopservice() 将调用服务类的 destroy 方法,现在您可以放置​​代码以断开正在进行的进程onDestroy().

经过如此努力,我得到了我的结果!希望你能得到你的答案!