java - 我的 Activity onPause/OnResume 方法每分钟无故调用一次

标签 java android

我有一个同时使用相机和 BLE MIDI 设备的应用程序。因为它使用相机,所以它使用 wakelock在 Activity 运行时保持屏幕处于 Activity 状态。

我还在 Activity 的 onPause、onResume 和 onUserLeaveHint 方法上添加了一些 logcat 消息。结果如下:

07-15 21:55:15.422 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-15 21:55:15.540 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [wakelock release]
07-15 21:55:15.541 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-15 21:55:15.597 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-15 21:56:16.701 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-15 21:56:16.931 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [wakelock release]
07-15 21:56:16.933 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-15 21:56:17.017 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-15 21:57:18.118 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-15 21:57:18.245 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [wakelock release]
07-15 21:57:18.246 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-15 21:57:18.307 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-15 21:58:55.196 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-15 21:58:55.331 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [wakelock release]
07-15 21:58:55.332 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-15 21:58:55.388 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]

由于我不明白的原因,某些原因导致我的 Activity 每分钟暂停一次,然后立即恢复。

虽然 onUseLeaveHint 在 onPause 之前被调用,但在此期间手机并未被触摸,它本身就在我的 table 上,屏幕打开。

以上是有问题的,因为我有 BLE 资源并且正在录制 MIDI 文件。如果我经常关闭并重新打开 MIDI 设备,我担心会导致录音中的计时问题。

这正常吗?如果没有,有什么想法为什么会发生这种情况吗?

这是我的 Activity :

package uk.co.mxklabs.pianoeye;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;

import uk.co.mxklabs.androidlib.music.midi.IMidiEventListener;
import uk.co.mxklabs.androidlib.music.midi.SimpleMidiEventAdapter;

public class CameraActivity extends Activity
        implements SharedPreferences.OnSharedPreferenceChangeListener
{

    private static final String TAG = "mxklogcat";

    private PowerManager.WakeLock m_wakeLock;
    private SimpleMidiEventAdapter m_midiAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        //getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if (null == savedInstanceState)
        {
            getFragmentManager().beginTransaction()
                    .replace(R.id.container, Camera2VideoFragment.newInstance())
                    .commit();
        }

        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        m_wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);

        m_midiAdapter = new SimpleMidiEventAdapter(this.getApplicationContext(), "");
        //m_midiAdapter.addMidiEventListener(mSurfaceView);
        m_midiAdapter.addMidiEventListener(new IMidiEventListener()
        {
            @Override
            public void noteOn(int channel, int midiNote, int velocity)
            {
                Log.v(TAG, "Note " + Integer.toString(midiNote) + " on, velocity " + Integer.toString(velocity) + "!");
            }

            @Override
            public void noteOff(int channel, int midiNote, int velocity)
            {
                Log.v(TAG, "Note " + Integer.toString(midiNote) + " off!");
            }
        });
    }

    @Override
    public void onResume()
    {
        Log.v(TAG, "CameraActivity [onResume]");
        super.onResume();
        m_midiAdapter.onResume();

        Log.v(TAG, "WakeLock [wakelock acquire]");
        m_wakeLock.acquire();

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        prefs.registerOnSharedPreferenceChangeListener(this);
        //processVideoOverlayTransparencyValue(prefs);
        processMidiDevice(prefs);
    }

    @Override
    protected void onUserLeaveHint()
    {
        Log.v(TAG, "CameraActivity [onUserLeaveHint]");
        super.onUserLeaveHint();
    }

    @Override
    public void onPause()
    {
        Log.v(TAG, "CameraActivity [wakelock release]");
        m_wakeLock.release();

        Log.v(TAG, "CameraActivity [onPause]");
        m_midiAdapter.onPause();
        super.onPause();

        // TODO: Make consistent pause/onPause.
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState)
    {
        Log.v(TAG, "CameraActivity [onCreate]");
        super.onCreate(savedInstanceState, persistentState);
    }

    @Override
    protected void onStart()
    {
        Log.v(TAG, "CameraActivity [onStart]");
        super.onStart();
    }

    @Override
    protected void onRestart()
    {
        Log.v(TAG, "CameraActivity [onRestart]");
        super.onRestart();
    }

    @Override
    protected void onStop()
    {
        Log.v(TAG, "CameraActivity [onStop]");
        super.onStop();
    }

    @Override
    protected void onDestroy()
    {
        Log.v(TAG, "CameraActivity [onDestroy]");
        super.onDestroy();
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
    {
        if (key == "pref_bluetooth_midi_select_device")
        {
            processMidiDevice(sharedPreferences);
        }

        Log.v(TAG, "Preference \"" + key + "\" changed");
    }

    public void processMidiDevice(SharedPreferences sharedPreferences)
    {
        final String MIDI_DEVICE_ID = sharedPreferences.getString("pref_bluetooth_midi_select_device", "");

        m_midiAdapter.changeMidiDeviceId(MIDI_DEVICE_ID);
    }

    public void handleSettingsButtonClick(View v)
    {
        Log.v(TAG, "setting_button clicked");

        Intent intent = new Intent(this, SettingsActivity.class);
        //myIntent.putExtra("key", value); //Optional parameters
        this.startActivity(intent);

    }

}

这是我的 list :

<?xml version="1.0" encoding="utf-8"?><!--
 Copyright 2014 The Android Open Source Project

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="uk.co.mxklabs.pianospy"
    android:versionCode="1"
    android:versionName="1.0">

    <!-- Min/target SDK versions (<uses-sdk>) managed by build.gradle -->

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <uses-permission android:name="android.permission.WAKE_LOCK"/>

    <application android:allowBackup="true"
        android:label="@string/app_name"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/Theme.AppCompat.Light">

        <activity android:name=".CameraActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SettingsActivity"
            android:label="@string/title_activity_settings"
            android:parentActivityName=".MainActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="uk.co.mxklabs.pianoeye.MainActivity" />
        </activity>

    </application>
</manifest>

我不希望我的 Activity 每分钟左右暂停并立即恢复。

编辑:我尝试了唤醒锁的替代方案(例如 FLAG_KEEP_SCREEN_ON),其行为相同:

07-16 19:53:26.799 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-16 19:53:26.934 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-16 19:53:26.997 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-16 19:54:28.111 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-16 19:54:28.224 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-16 19:54:28.291 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-16 19:55:29.369 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-16 19:55:29.491 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-16 19:55:29.560 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-16 19:56:30.647 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-16 19:56:30.771 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause
07-16 19:56:30.847 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]

编辑:这是一个展示相同行为并使用 FLAG_KEEP_SCREEN_ON 的最小示例:

package uk.co.mxklabs.testapp.myapplication;

import android.os.PersistableBundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;

public class MainActivity extends AppCompatActivity
{

    private static final String TAG = "mxklogcat";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    @Override
    public void onResume()
    {
        Log.v(TAG, "MainActivity [onResume]");
        super.onResume();
    }

    @Override
    protected void onUserLeaveHint()
    {
        Log.v(TAG, "MainActivity [onUserLeaveHint]");
        super.onUserLeaveHint();
    }

    @Override
    public void onPause()
    {
        Log.v(TAG, "MainActivity [onPause]");
        super.onPause();
    }
}

已解决:我注意到此问题在另一部手机上没有发生,并认为可能是另一个应用程序导致了此问题。我卸载了手机上一半的应用程序,这个问题就消失了。

最佳答案

你正在做documentation的事情已直接告诉您不要这样做。

Creating and holding wake locks can have a dramatic impact on the host device's battery 
life. Thus you should use wake locks only when strictly necessary and hold them 
for as short a time as possible. For example, you should never need to use a wake lock 
in an activity. As described above, if you want to keep the screen on in your activity, 
use FLAG_KEEP_SCREEN_ON.
<小时/>

您应该利用FLAG_KEEP_SCREEN_ON并将CPU密集型工作转移到后台服务。使用BroadcastReciever通知并完成您的录制工作。

关于java - 我的 Activity onPause/OnResume 方法每分钟无故调用一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57047235/

相关文章:

安卓 : detect click event at empty space of gridview inside linearlayout

java - 回复kafka模板连接 header (CorrelationId)未发送到Google pub sub

Java 从 For 循环初始化 ArrayList

android - WebView getScrollY() 总是返回 0

java - android如何在触摸事件中每3秒在随机x y中绘制位图

android - 无法从 Assets 打开 FileInputStream

java - 如何在toast消息中隐藏包名称?

java - 为什么 TestNG Selenium 并行方法不起作用?

java - 非常小的代码优化

java - Jenkins Maven项目本环境未提供编译器