【问题标题】:MyApplication's method returns wrong valueMyApplication 的方法返回错误的值
【发布时间】:2014-07-24 01:13:04
【问题描述】:

我有一个这样的应用程序类:

public class MyApplication extends Application {
    private static boolean FOCUSED;

    public static boolean isAppFocused() {
        Log.v("@@@@@@  isAppFocused", "called");
        return FOCUSED;
    }  

    public static void appResumed() {
        Log.v("@@@@@@  appResumed", "called");
        FOCUSED = true;
    }

    public static void appPaused() {
        Log.v("@@@@@@  appPaused", "called");
        FOCUSED = false;
    }  
}

在我的 MainActivity 中,我这样调用它的方法:

@Override
protected void onResume() {
    super.onResume();
    MyApplication.appResumed();
}

@Override
protected void onPause() {
    super.onPause();
    MyApplication.appResumed();
}

如您所见,我从未调用过 MyApplication.appPaused();方法。 而 FOCUSED 变量在 MyApplication 中的默认值为 null。

奇怪的是,当我在服务内部调用 isAppFocused() 时,它返回 false !!!!!

我想知道应用程序是否获得焦点,以便它不会在服务内显示通知。 在此之前我什至使用过 SharedPreferences,但也遇到了同样的问题,无论如何,它们的价值不会是我所期望的。 :|

我不知道为什么它不想让我知道应用程序是否有焦点。 :|我很生气。

编辑: 我将 Application 类更改为:

public class MyApplication extends Application {
    private static String FOCUSED;

    public static String isAppFocused() {
        Log.v("@@@@@@  isAppFocused", "called");
        return FOCUSED;
    }  

    public static void appResumed() {
        Log.v("@@@@@@  appResumed", "called");
        FOCUSED = "true";
    }

    public static void appPaused() {
        Log.v("@@@@@@  appPaused", "called");
        FOCUSED = "false";
    }  
}

现在在 Service 中我正在使用它:

if(MyApplication.isAppFocused().equals("false")){
  //show notifications
}

现在它抛出 NullPointerException,但我在 logcat 中看到 appResumed() 方法在调用 isAppFocused() 之前被调用了两次。

AndroidManifest.xml 内:

<application
    android:allowBackup="false"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:uiOptions="splitActionBarWhenNarrow" android:supportsRtl="true">



    <!-- Splash screen -->
    <activity
        android:name="com.example.SplashScreen"
        android:screenOrientation="portrait"
        android:theme="@android:style/Theme.Black.NoTitleBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <!-- Main activity -->
    <activity
        android:name="com.example.MainActivity"
        android:configChanges="orientation|screenSize|keyboardHidden"
        android:launchMode="singleTask"
        android:label="@string/app_name" >
    </activity>

    <!-- Login activity -->
    <activity 
        android:name="com.example.Login"
        android:screenOrientation="portrait">
    </activity>

    <!-- Push Service -->
    <receiver android:name="com.example.service.MyBroadcast" 
              android:enabled="true" 
              android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
    <service android:name="com.example.service.MyService"
             android:process=":My_Service_Process"
        />

</application>
<application
    android:name="com.example.MyApplication" >

</application>

编辑 2: 我在 MainActivity 里面改了:

@Override
protected void onResume() {
    super.onResume();
    MyApplication.appResumed();
    Log.v("**** isAppFocused", MyApplication.isAppFocused());  
}

@Override
protected void onPause() {
    super.onPause();
    MyApplication.appPaused();
    Log.v("**** isAppFocused", MyApplication.isAppFocused());  
}

结果正确,onResume 返回“true”,onPause 返回“false”。 但在服务内部,它总是返回默认值“true”; 我不知道为什么它在 MainActivity 内部发生了变化,但它在服务内部没有变化。

Application 类的愤怒版:

public class MyApplication extends Application {
    private static String FOCUSED = "true";

    public static String isAppFocused() {
        Log.v("@@@@@@  isAppFocused", "called");
        return FOCUSED;
    }  

    public static void appResumed() {
        Log.v("@@@@@@  appResumed", "called");
        FOCUSED = "true";
    }

    public static void appPaused() {
        Log.v("@@@@@@  appPaused", "called");
        FOCUSED = "false";
    }  
} 

【问题讨论】:

  • 请有人尝试这样做,如果可行,请在此处发布您的代码。我正在使用后台服务推送通知,它应该在应用程序集中时返回 true,如果没有集中则返回 false。我想在我的服务中访问这些信息,该服务在不同的线程上运行。看看你能不能完成这样的事情。谢谢。
  • FOCUSED 标志的用途是什么?你能详细说明一下吗?
  • 它保存了应用程序的状态。如果应用程序被恢复,它应该是真的;
  • 问题是这似乎是另一个问题的解决方案。您尝试使用此标志解决的原始问题是什么?
  • 没问题,我希望我的服务仅在主应用有焦点时才显示通知。

标签: java android


【解决方案1】:

根据Within an application, will the activity and service run in the same process?,您的Service 和Activity 运行在不同的进程中。这意味着您的活动对任何变量所做的任何更改对服务都是不可见的。您需要找到另一种方式在服务和活动之间进行通信。请参阅Communication between Service and Activity on Android 获取建议。

【讨论】:

  • 有很多方法,一种方法是广播接收器,一种方法是使用 sharedpreferences,我尝试过并且遇到了同样的问题,一种方法是使用 Application 类。那么我该如何解决这个问题?换一种方式不是解决办法。
  • 我只是想检查应用是否有焦点,这有多难?
  • @MDP 您不能使用 Application 类,因为您在每个进程中有两个单独的实例。 SharedPreferences 可能有同样的问题。我不完全确定,因为我不熟悉它们。
  • @MDP 另一种选择是在 Activity 的 onResume() 中启动服务并在 onPause() 中停止。
  • 服务的重点是即使应用程序没有运行也能运行,这就是我将其设为 android.intent.action.BOOT_COMPLETED 的原因。我无法阻止它。 SharedPreferences 在文件上写入信息,因此每个人都可以访问它,并且它工作了一段时间,但我不知道为什么它没有改变相同的键值,我在 Application 类中遇到的同样的问题。我想检查应用程序是否有焦点,不显示通知,我不想停止整个服务。我该怎么做?
猜你喜欢
  • 2023-04-02
  • 1970-01-01
  • 2020-08-10
  • 2016-02-01
  • 1970-01-01
  • 2019-10-08
  • 2019-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多