动态壁纸关闭后还是运行

Live wallpaper is still running after i close it

我正在 Android 上学习动态壁纸。我注意到我的墙纸仍然是 运行,尽管我 select 另一个墙纸。要重现此行为,我将使用一个简单的动态壁纸。 清单是:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.wallpaper.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="23" />

    <uses-feature android:name="android.software.live_wallpaper" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <service
            android:name=".DemoWallpaperService"
            android:label="Demo Live Wallpaper"
            android:permission="android.permission.BIND_WALLPAPER" >
            <intent-filter>
                <action android:name="android.service.wallpaper.WallpaperService" />
            </intent-filter>

            <meta-data
                android:name="android.service.wallpaper"
                android:resource="@xml/wallpaper" />
        </service>
    </application>

</manifest>

服务代码为:

package org.wallpaper.test;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.SurfaceHolder;

public class DemoWallpaperService extends WallpaperService {
    @Override
    public Engine onCreateEngine() {
        Log.i("DemoWallpaperService","DemoWallpaperService > onCreateEngine");      
        return new DemoWallpaperEngine();
    }

    @Override
    public void onCreate() {
        Log.i("DemoWallpaperService","DemoWallpaperService > onCreate");    
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.i("DemoWallpaperService","DemoWallpaperService > onDestroy");   
        super.onDestroy();
    }

    private class DemoWallpaperEngine extends Engine {
        private boolean mVisible = false;
        private final Handler mHandler = new Handler();
        private final Runnable mUpdateDisplay = new Runnable() {
            @Override
            public void run() {
                draw();
            }
        };

        private void draw() {
            SurfaceHolder holder = getSurfaceHolder();
            Canvas c = null;
            try {
                c = holder.lockCanvas();
                if (c != null) {
                    Paint p = new Paint();
                    p.setTextSize(20);
                    p.setAntiAlias(true);
                    String text = "system time: " + Long.toString(System.currentTimeMillis());
                    float w = p.measureText(text, 0, text.length());
                    int offset = (int) w / 2;
                    int x = c.getWidth() / 2 - offset;
                    int y = c.getHeight() / 2;
                    p.setColor(Color.BLACK);
                    c.drawRect(0, 0, c.getWidth(), c.getHeight(), p);
                    p.setColor(Color.WHITE);
                    c.drawText(text, x, y, p);
                }
            } finally {
                if (c != null)
                    holder.unlockCanvasAndPost(c);
            }
            mHandler.removeCallbacks(mUpdateDisplay);
            if (mVisible) {
                mHandler.postDelayed(mUpdateDisplay, 100);
            }
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            mVisible = visible;
            if (visible) {
                draw();
            } else {
                mHandler.removeCallbacks(mUpdateDisplay);
            }
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            draw();
        }

        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            mVisible = false;
            mHandler.removeCallbacks(mUpdateDisplay);
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            mVisible = false;
            mHandler.removeCallbacks(mUpdateDisplay);
        }
    }
}

编译后,在设备上部署并select它。

现在我 select 另一个墙纸,所以我希望墙纸进程结束。如果我去 DDMS,我看到进程仍然是 运行:

还有很多线程还活着:

这是正确的,还是壁纸没有正常关闭?

谢谢

经过调查我发现,尽管调用了服务的 onDestroy 方法,墙纸仍然存在。该进程被放入缓存进程中。如果您重新选择它,可以更快地恢复它。

当内存被占用时,进程将被终止。