Android 从IntentHandler传递给需要上下文的方法的上下文是什么?
我刚刚添加了一个新条件的检查,该条件可能出现在使用“借用”代码显示消息的长时间工作的应用程序中 该语句位于类Android 从IntentHandler传递给需要上下文的方法的上下文是什么?,android,android-context,android-intentservice,Android,Android Context,Android Intentservice,我刚刚添加了一个新条件的检查,该条件可能出现在使用“借用”代码显示消息的长时间工作的应用程序中 该语句位于类DbQuery的IntentHandler中,该类扩展了IntentService: showMessage(getApplicationContext(), "title", "note", mDatabase); // LINE 576 **** //send a broadcast intent from your service Intent intent = new Inten
DbQuery
的IntentHandler
中,该类扩展了IntentService
:
showMessage(getApplicationContext(), "title", "note", mDatabase); // LINE 576 ****
//send a broadcast intent from your service
Intent intent = new Intent();
intent.setAction(BROADCAST_FILTER);
intent.putExtra("message", "<your message here>")
sendBroadcast(intent);
showMessage
是在类Utilities
中定义的,一直有效,直到我决定在我的Android 4平板电脑上使用它(19):
它调用发生异常的方法(标记为*****):
从MainActivity
调用showMessage
,其中传递的上下文是this
我想我不应该尝试从我的管理员那里调用showMessage
,但我想知道应该如何调用它。
也就是说,我应该通过什么Context
?
对于showMessage
的第一个参数,我尝试了this
,getApplicationContext()
,getApplication()
,getApplication().getApplicationContext()
,以及getBaseContext()
。全部返回以下错误。我甚至为builder.setPositiveButton提供了一个监听器,而不是null
。同样的错误:
E: FATAL EXCEPTION: IntentService[QueryDb]
Process: com.dslomer64.sqhell, PID: 24814
android.view.WindowManager$BadTokenException: Unable to add window --
token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:571)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:310)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.app.Dialog.show(Dialog.java:319)
at android.app.AlertDialog$Builder.show(AlertDialog.java:1112)
at com.dslomer64.sqhell.Utilities.showCenteredInfoDialog(Utilities.java:482)
at com.dslomer64.sqhell.Utilities.showMessage(Utilities.java:505)
at com.dslomer64.sqhell.QueryDb.onHandleIntent(QueryDb.java:576)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
E: getSlotFromBufferLocked: unknown buffer: 0xb40fe560
下面是调试跟踪部分的打印屏幕
您应该使用此错误的活动上下文,我希望已解决此错误
私有上下文
在onCreate方法中初始化此上下文,如下所示
上下文=此;//并使用此上下文
showMessage(上下文,“标题”,“注释”,mDatabase)
并在singleton类中创建一个上下文类型变量,用作全局验证。对于此错误,您应该使用活动上下文,我希望已解决此错误
私有上下文
在onCreate方法中初始化此上下文,如下所示
上下文=此;//并使用此上下文
showMessage(上下文,“标题”,“注释”,mDatabase)
还可以在singleton类中创建一个上下文类型变量,用作全局验证。一般来说,当周围没有活动时,Android服务可能正在运行。它只是Android中的另一个核心实体,比如Activity
或BroadcastReceiver
如果你的安卓服务
不负责更新用户界面,而是向你的活动
发送足够的数据来更新用户界面,那么它会更干净。例如,您的Android服务
可以使用Broadcast
发送消息,而活动
可以通过BroadcastReceiver
收听这些消息
在服务中定义BROADCAST\u FILTER
,以便BroadcastReceiver
能够识别来自服务的消息意图:
public static String BROADCAST_FILTER = <Your service class>.class.getName();
在您的活动中注册BroadcastReceiver
:
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra();
Utils.showMessage(<your activity>.this, ...);
//do your update here
}
};
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
//make sure your onReceive receives only the messages with this action
filter.addAction(<Your Service>.BROADCAST_FILTER);
registerReceiver(receiver, filter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
private BroadcastReceiver=new BroadcastReceiver(){
@凌驾
公共void onReceive(上下文、意图){
String message=intent.getStringExtra();
Utils.showMessage(.this,…);
//请在这里更新
}
};
@凌驾
受保护的void onResume(){
super.onResume();
IntentFilter=newintentfilter();
//确保onReceive仅接收具有此操作的消息
filter.addAction(.BROADCAST\u filter);
寄存器接收器(接收器、过滤器);
}
@凌驾
受保护的void onPause(){
super.onPause();
未注册接收人(接收人);
}
一般来说,当周围没有活动时,Android服务可能正在运行。它只是Android中的另一个核心实体,比如Activity
或BroadcastReceiver
如果你的安卓服务
不负责更新用户界面,而是向你的活动
发送足够的数据来更新用户界面,那么它会更干净。例如,您的Android服务
可以使用Broadcast
发送消息,而活动
可以通过BroadcastReceiver
收听这些消息
在服务中定义BROADCAST\u FILTER
,以便BroadcastReceiver
能够识别来自服务的消息意图:
public static String BROADCAST_FILTER = <Your service class>.class.getName();
在您的活动中注册BroadcastReceiver
:
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra();
Utils.showMessage(<your activity>.this, ...);
//do your update here
}
};
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
//make sure your onReceive receives only the messages with this action
filter.addAction(<Your Service>.BROADCAST_FILTER);
registerReceiver(receiver, filter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
private BroadcastReceiver=new BroadcastReceiver(){
@凌驾
公共void onReceive(上下文、意图){
String message=intent.getStringExtra();
Utils.showMessage(.this,…);
//请在这里更新
}
};
@凌驾
受保护的void onResume(){
super.onResume();
IntentFilter=newintentfilter();
//确保onReceive仅接收具有此操作的消息
filter.addAction(.BROADCAST\u filter);
寄存器接收器(接收器、过滤器);
}
@凌驾
受保护的void onPause(){
super.onPause();
未注册接收人(接收人);
}
由于我的应用程序的性质,在问我的问题之前,我已经有了一个BroadcastManager
和一个BroadcastReceiver
,所以我已经尝试了自己的微弱尝试,类似于@user805311的建议
我说的基本上是对的,我只是不应该尝试在IntentService
中showMessage
,尽管@nishant的链接展示了如何做到这一点
我对现行守则所作的修改如下:
在IntentService
中QueryDb
的publishProgress
中,我在顶部的if
中添加了代码,以通过另一个Intent
而不是showMessage
传递消息(存储在progress
),而不是showMessage
,从而导致异常,并立即开始通过关闭进程
public class QueryDb extends IntentService
{
...
private void publishProgress(String progress)
{
Intent intent = new Intent(MatchesActivity.SOME_ACTION);
if(progress.toLowerCase().startsWith("Revise"))
{
intent.putExtra(MatchesActivity.STRING_EXTRA_NAME, progress);
onPostExecute();
}
else ...
...
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
String messageText = "Revise code!";
publishProgress(messageText);
public class MatchesActivity extends Activity implements QueryDb.DbProcListenerForQueryDb
{
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver()
{
@Override public void onReceive(Context context, Intent intent)
{
String s = intent.getStringExtra(STRING_EXTRA_NAME) ;
if(s.startsWith("Revise"))
{
showMessage(_context, "Oh, no...", s, null);
MatchesActivity.this.setResult(RESULT_CANCELED);
}
else ...
...
}; // BroadcastReceiver
public class MainActivity extends Activity
{
...
@Override protected void onActivityResult(int requestCode, int resultCode, Intent intentData)
{
if(resultCode != RESULT_OK)
{
showMessage(this, "Bad news", "Only Scrabble", mDatabase);
return;
}
...