使用 wakelock.release() 关闭应用程序时,Android 应用程序崩溃

Posted

技术标签:

【中文标题】使用 wakelock.release() 关闭应用程序时,Android 应用程序崩溃【英文标题】:Android app crashed when closing app using wakelock.release() 【发布时间】:2015-10-24 08:49:50 【问题描述】:

我有一个运行良好的简单闪光灯应用程序,但是当用户关闭应用程序时,应用程序崩溃了。我认为问题出在唤醒锁上。

当闪光灯打开时唤醒锁打开,当闪光灯关闭时唤醒锁关闭。这可以正常工作,但一旦用户按下返回或主页,应用就会崩溃。

我的日志数据:

10-24 09:52:45.235:E/androidRuntime(6614):进程: r1d.org.uk.flashlight,PID:6614 10-24 09:52:45.235: E/AndroidRuntime(6614): java.lang.RuntimeException: 无法销毁 活动 r1d.org.uk.flashlight/r1d.org.uk.flashlight.MainActivity: java.lang.RuntimeException:WakeLock 未锁定 MyWakelockTag 10-24 09:52:45.235:E/AndroidRuntime(6614):在 android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3812)

主活动:

public class MainActivity extends Activity 

    private ImageView lightToggle;
    private ImageButton lightSwitch;
    Camera camera = null;
    Parameters parameters;
    Boolean isOn = false;
    int lightON = R.drawable.on;
    int lightOFF = R.drawable.off;
    int switchON = R.drawable.switch_on;
    int switchOFF = R.drawable.switch_off;
    Boolean hasFlash;
    PowerManager powerManager;
    PowerManager.WakeLock wakeLock;

    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AdManager ads = new AdManager(this);
        lightToggle = (ImageView) findViewById(R.id.lightOn);
        lightSwitch = (ImageButton) findViewById(R.id.lightSwitch);
        Context context = this;
        hasFlash = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
        powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag");

        if(!hasFlash)
            ContextThemeWrapper themedContext;
            if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) 
                themedContext = new ContextThemeWrapper( MainActivity.this, android.R.style.Theme_Holo_Light_Dialog_NoActionBar );
            
            else 
                themedContext = new ContextThemeWrapper( MainActivity.this, android.R.style.Theme_Light_NoTitleBar );
            
            AlertDialog.Builder builder = new AlertDialog.Builder(themedContext);
            builder.setTitle(getResources().getString(R.string.notsupported))
                    .setMessage(getResources().getString(R.string.notsupportedinfo))
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setNegativeButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener() 
                        @Override
                        public void onClick(DialogInterface dialog, int i) 
                            dialog.cancel();
                        
                    );
            builder.show();
        
        turnOn();
        lightSwitch.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                if(isOn)
                    turnOff();
                 else 
                    turnOn();
                
            
        );
    
    private void turnOn()
        lightToggle.setImageDrawable(getResources().getDrawable(lightON));
        lightSwitch.setImageDrawable(getResources().getDrawable(switchON));
        wakeLock.acquire();
        if(hasFlash) 
            camera = Camera.open();
            parameters = camera.getParameters();
            parameters.setFlashMode(Parameters.FLASH_MODE_TORCH); //FLASH_MODE_ON
            camera.setParameters(parameters);
        
        isOn = true;
    
    private void turnOff()
        lightToggle.setImageDrawable(getResources().getDrawable(lightOFF));
        lightSwitch.setImageDrawable(getResources().getDrawable(switchOFF));
        wakeLock.release();
        if(hasFlash) 
            parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(parameters);
            camera.release();
            camera = null;
        
        isOn = false;
    
    @Override
    public void onDestroy() 
        turnOff();
        super.onDestroy();
    
    @Override
    public void onPause()
        turnOff();
        super.onPause();
    
    @Override
    public void onResume()
        turnOn();
        super.onResume();
    

【问题讨论】:

【参考方案1】:

onDestroy 中,您尝试释放已在onPause 中释放的唤醒锁。这应该有效:

if (wakeLock.isHeld()) 
    wakeLock.release();

【讨论】:

以上是关于使用 wakelock.release() 关闭应用程序时,Android 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

WCF 基础连接已经关闭: 服务器关闭了本应保持活动状态的连接。

左或右应表示为布尔值还是枚举[关闭]

c#对数据库访问完应关闭连接

C套接字HTTP 1.1持久连接服务器何时应关闭套接字?

无需使用d3.js重新渲染数据的无限滚动条形图[关闭]

该函数应返回字符串乘以整数[关闭]