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;
    }
    ...