是什么区别getContext(),getApplicationContext(),getBaseContext(),和" this"?
虽然这是一个简单的问题,但我无法理解它们之间的基本区别.如果可能,请举出一些简单的例子.
我是新来的Android和我想明白之间的差别getApplication(),getApplicationContext()getBaseContext(),getContext()以及someClass.this特别是当使用这些方法在下面的代码行:
当我发起祝酒时,这些和我使用它们之间有什么区别?
Toast.makeText(LoginActivity.this, "LogIn successful", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplication(), "LogIn successful", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), "LogIn successful", Toast.LENGTH_SHORT).show();
Toast.makeText(getBaseContext(), "LogIn successful", Toast.LENGTH_SHORT).show();
Run Code Online (Sandbox Code Playgroud)
与意图相同:
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
Intent intent = new Intent(MenuPagina., LoginActivity.class);
Intent intent = new Intent(getBaseContext(), LoginActivity.class);
Intent intent = new Intent(getApplication(), LoginActivity.class);
Run Code Online (Sandbox Code Playgroud) 我已经实现了一个由AlarmManager触发的BroadcastReceiver.AlarmManager在BOOT_COMPLETED上初始化.所以我必须在清单中声明接收器.
我的问题是我希望BroadcastReceiver只在我自己的活动都不在前台时做某事(也就是说用户没有与我的应用程序交互).我从远程服务器提取信息,并且不想通知用户他当前是否在我的应用程序中.
到目前为止,我还没有找到一种方法来确定我的应用程序是否在前台.有没有办法做这样的事情?ActivityManager告诉我我的应用程序是否正在运行,但不是它是否在前台.
问题与此处描述的几乎相同:只有在广播接收器处于前台时才通知它
解:
在评估了几个解决方案后,我想快速概述一下我认为在后台/前台处理活动的最佳方法.
首选方法是在活动的onResume方法中注册广播接收器,并在onPause上的活动上注销它.任何服务或其他背景元素都需要通过您的活动将拦截的特定操作发送广播意图.
如果您的活动位于前台,它将使其意向接收者注册,并能够直接处理您的服务发送的意图.如果它不在前台,它将不会接收到意图,但是调用广播的服务将知道没有人截获其广播意图并且能够自己处理它.例如,它可以启动所需的活动,显示通知等.
在Developer Console中,我看到很多像这样的堆栈跟踪崩溃
java.lang.RuntimeException:
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2984)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14(ActivityThread.java:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method:0)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Caused by: java.lang.ClassCastException:
at com.myapp.ui.BaseActivity.getApp(BaseActivity.java:193)
at com.myapp.ui.BaseActivity.onCreate(BaseActivity.java:275)
at com.myapp.ui.CastActivity.onCreate(CastActivity.java:39)
at com.myapp.ui.MainActivity.onCreate(MainActivity.java:268)
at android.app.Activity.performCreate(Activity.java:6955)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)
Run Code Online (Sandbox Code Playgroud)
BaseActivity的getApp方法是
public App getApp() {
return (App) getApplication();
}
Run Code Online (Sandbox Code Playgroud)
App类是
public class App extends MultiDexApplication { ...
Run Code Online (Sandbox Code Playgroud)
并且在manifest应用程序标记中包含对此类的引用
<application
android:name="com.myapp.App"
Run Code Online (Sandbox Code Playgroud)
98%的崩溃是针对Android 7.0,休息是7.1.没有其他Android版本受到影响.
编辑:我使用proguard所以它可以以某种方式相关但保持类
-keep class com.myapp.** { *;}
-keep interface com.myapp.** { *;}
Run Code Online (Sandbox Code Playgroud)
注意:它可能没有关系,但在相同的Android版本中,它看起来像App的onCreate方法有时不被调用.我观察它是因为在onCreate中创建的某些对象在从Service(由AlarmManager启动)或BroadcastReceiver访问时为null
有谁知道什么可以导致它,如何解决它或解决它?谢谢
编辑2:我最终得到了这样的东西:
public App getApp() …Run Code Online (Sandbox Code Playgroud) 有没有办法从Context获取应用程序.我注意到activity和service有getApplication()方法,但Context没有.
背景:
我正在使用/扩展GCMBaseIntentService和
protected abstract void onMessage (Context context, Intent intent)
Run Code Online (Sandbox Code Playgroud)
给我一个上下文作为参数.我想获取Application对象,以便我可以将它转发到MyApplication并检索一些变量
谢谢
我有一个存储应用程序上下文信息的应用程序 应用程序上下文信息在MyApp类中的活动之间共享,该类扩展了Application类.
我正在为我的活动编写单元测试,我想检查当用户单击活动中的按钮时,应用程序状态将发生变化.像这样的东西:
@Override
public void onClick(View pView) {
((MyApp)getApplicationContext()).setNewState();
}
Run Code Online (Sandbox Code Playgroud)
问题是我不知道如何模拟该应用程序上下文.我使用ActivityUnitTestCase作为测试用例库.当我调用setApplication时,它会更改Activity类的mApplication成员的值,但不会更改应用程序上下文的值.我也尝试过setActivityContext,但它似乎不对(它不是应用程序上下文而是活动上下文)并且它在startActivity中触发断言).
所以问题是 - 如何模拟getApplicationContext()?
请考虑以下代码.在Service.onStart()方法中我已经创建并启动了一个应该显示Toast消息的线程,但它不起作用!
public class MyService extends Service{
private static final String TAG = "MyService";
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onCreate()
{
Toast.makeText(this, "My Service Created", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy()
{
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_SHORT).show();
}
@Override
public void onStart(Intent intent, int startid)
{
Toast.makeText(this, "My Service Started", Toast.LENGTH_SHORT).show();
DBIteratorThread dbThread=new DBIteratorThread();
dbThread.myService=this;
Thread t1 = new Thread(dbThread);
t1.start();
}
}
class DBIteratorThread implements Runnable
{
MyService myService;
public void …Run Code Online (Sandbox Code Playgroud) 在应用程序的某个地方,我需要使用getString方法获取本地化字符串以获取错误消息.为此,我需要一个Context实例,例如来自一个Activity.这真的是这个设计的吗?我真的被迫将这些对象传递给类和方法,或者我错过了这一点,还有其他方法来获取字符串引用吗?
为了澄清,在一个Activity中,我有一个内部AsyncTask子类,在doInBackground中实例化一个新类,用于UI线程之外的一些短网络处理.我希望错误消息被本地化,为此我需要将Context实例(换句话说,Activity)传递到该类中.从XML文件中获取价值资源的设计似乎有点不直观.它让我想知道为什么它与Context实例结合在一起而不是静态的东西或者 - 请原谅我 - 一个单例,因为Context暗示是全局应用程序上下文而不仅仅是一个Activity的一部分.
我想在广播接收器中检查互联网连接; 并将结果(一个布尔标志)设置为全局变量,以便在整个应用程序中使用它,如果条件; 如果互联网断开连接,请在主活动中将状态图像视图设置为红色图像,如果已连接,则将其设置为绿色.
我跟着这个话题.但getApplication()广播接收器中没有; 而我应该使用getApplicationContext().
另一方面,这个话题:
当在广播接收器中编写代码时,它不是上下文但在其onReceive方法中给出了上下文,您只能调用getApplicationContext().这也意味着您无法保证能够在BroadcastReceiver中访问您的应用程序.
有什么顾虑?
如何在广播Receiver中访问我的应用程序类?
是否有更好的解决方案来检查互联网连接,设置全局变量和更改我的状态imageview?
android broadcastreceiver android-lifecycle android-broadcast
我正在尝试使用Room作为单身人士,所以我不必再调用Room.databaseBuilder()- 这是昂贵的 - 不止一次.
@Database(entities = arrayOf(
Price::class,
StationOrder::class,
TicketPrice::class,
Train::class,
TrainCategory::class
), version = 2)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun dao(): TrainDao
companion object {
fun createDatabase(context: Context): AppDatabase
= Room.databaseBuilder(context, AppDatabase::class.java, "trains.db").build()
}
}
Run Code Online (Sandbox Code Playgroud)
注意:
abstract class.Context作为一个论点.我查看了所有类似的StackOverflow问题,但没有一个满足我的要求
在Kotlin中使用参数的Singleton 不是线程安全的
Kotlin - 在Android中转换Singleton DatabaseController的最佳方法 不是线程安全的
Kotlin线程使用参数 使用对象保存本机惰性单例
android ×10
java ×2
this ×2
android-room ×1
architecture ×1
junit ×1
kotlin ×1
singleton ×1
toast ×1
unit-testing ×1