代码之家  ›  专栏  ›  技术社区  ›  DSlomer64

从intenthandler传递到需要它的方法的上下文是什么?

  •  0
  • DSlomer64  · 技术社区  · 8 年前

    我刚刚添加了一个检查在使用“借用”代码显示消息的长时间工作应用程序中可能出现的新情况的检查。

    语句位于 intenthandler for class dbquery ,which extends intentservice :。

    showMessage(getApplicationContext(),“title”,“note”,mdatabase);//第576行****
    

    showmessageis defined in classutilitiesand had always worked,until I determined to see that it works on my android 4 tablet(19):(代码>显示消息>在类中定义,并且一直有效,直到我决定在我的android 4

    public static void showmessage(context mcontext,string tit,string m m,sqliteDatabase m)
    {
    textView message=new textView(mcontext);
    textView title=新建textView(mcontext);
    标题。设置文本(标题);
    message.settext(毫米);
    ShowCenteredInfodialog(mcontext,title,message,gravity.center,m);//****第505行
    }
    

    它调用发生异常的方法(标记为*****):。

    public static void showcenteredinfodialog
    (
    上下文上下文,文本视图消息,文本视图标题,int
    重力,sqlite数据库m
    )
    {
    context.getSystemService(context.layoutInflaterService);
    
    int黄色前景;
    在明亮的背景下;
    
    {
    YellowForeground=context.getResources().getColor(r.color.YellowForeground,空);
    明亮的背景=
    context.getresources().getcolor(r.color.brightbluebackground,空);
    
    title.settextcolor(黄色前景);
    标题.背景色(明亮的背景色);
    标题.设置重力(重力.中心);
    
    警报对话框.builder
    builder=new alertdialog.builder(上下文);
    builder.setpositivebutton(“确定”,空);
    builder.setcustomTitle(标题);
    builder.setMessage(message.getText());
    
    对话框
    对话;
    dialog=builder.show();//*******************************第482行
    dialog.setCanceledOntouchoutside(假);
    
    文本框
    messageview=/*(textview)*/dialog.findview byid(android.r.id.message);
    messageview.settextcolor(黄色前景);
    messageview.backgroundcolor(明亮的背景色);
    messageview.setttypeface(字体.monospace);
    messageview.setgravity(重力);
    }
    }
    

    调用showmessagework frommainactivity,其中contextpassed isthis

    我想我不应该试着从我的intenthandlershowmessagefrom myintenthandler,但是我想知道我应该如何调用它。 也就是说,我应该通过什么?

    对于showMessage的第一个参数,我尝试了this,getApplicationContext(),getApplicationContext(),getApplicationContext(),getBaseContext(),。全部返回以下错误。我甚至提供了一个监听器,而不是作为builder.setpositivebutton的第二个参数。相同错误:

    e:fatal exception:intentservice[querydb]
    进程:com.dslomer64.sqhell,PID:24814
    android.view.windowmanager$badtokenexception:无法添加窗口--
    令牌空值不适用于应用程序
    在Android上.View .ViefRoTimpL.StView(ViefRoTimpL.java:571)
    在安卓.View中。Windows管理器Goop.AdView(Windows管理器Goopy.java:310)
    在安卓.View中,Windows管理器IMP.AdView(Windows管理器IMP.java:85)
    在Android。App.Cudio.Sudio(对话。Java:319)
    在安卓.App.AdvtList$Builder .Sube(AdvutalCudi.java:1112)
    在COM.DSLROML64 .SqHel.Untudio.StucCaseDeNoFieldCudio(实用程序. Java:482)
    在COM.DSLROML64 .SqHel.Uptual.StudiMead(实用程序. Java:505)
    在COM.DSLROML64 .qHED.QueldB.OnHANDLePoT(QueDeld.java:576)
    在安卓.App.ItnService $Service Healther-HaldLeMeSeAd(IntService,Java:66)
    在安卓.OS.Halder-Debug消息(HANDL.java:102)
    在安卓.OS.Looper-Loo.(循环器.java:148)
    在安卓.OS.HANDLRT.Tr.Run(HooLrTyth.java:61)
    E:GetSlotFromBufferLocked:未知缓冲区:0xB40FE560
    
    
    

    下面是调试跟踪的一部分的打印屏幕。

    .IntentHandler对于班级DbQuery,其中extends IntentService以下内容:

    showMessage(getApplicationContext(), "title", "note", mDatabase); // LINE 576 ****
    

    showMessage在类中定义Utilities一直都在工作,直到我决定在我的Android 4平板电脑上工作(19):

      public static void showMessage(Context mContext, String tit, String mm, SQLiteDatabase m)
      {
        TextView message = new TextView(mContext);
        TextView title   = new TextView(mContext);
        title.setText(tit);
        message.setText(mm);
        showCenteredInfoDialog(mContext, title, message, Gravity.CENTER, m); // **** LINE 505
      }
    

    它调用发生异常的方法(标记为*****):

      public static void showCenteredInfoDialog
          (
                  Context context, TextView message, TextView title, int 
                  gravity, SQLiteDatabase m
          )
      {
        context.getSystemService(Context.LAYOUTINFLATERSERVICE);
    
        int YELLOWFOREGROUND ;
        int BRIGHTBLUEBACKGROUND ;
    
        {
          YELLOWFOREGROUND = context.getResources().getColor(R.color.yellowforeground, null);
          BRIGHTBLUEBACKGROUND =
              context.getResources().getColor(R.color.brightbluebackground, null);
    
          title.setTextColor(YELLOWFOREGROUND);
          title.setBackgroundColor(BRIGHTBLUEBACKGROUND);
          title.setGravity(Gravity.CENTER);
    
          AlertDialog.Builder
              builder = new AlertDialog.Builder(context);
              builder.setPositiveButton("OK", null);
              builder.setCustomTitle(title);
              builder.setMessage(message.getText());
    
          AlertDialog
              dialog;
              dialog = builder.show(); // *************************** LINE 482
              dialog.setCanceledOnTouchOutside(false);
    
          TextView
          messageView = /*(TextView)*/ dialog.findViewById(android.R.id.message);
          messageView.setTextColor(YELLOWFOREGROUND);
          messageView.setBackgroundColor(BRIGHTBLUEBACKGROUND);
          messageView.setTypeface(Typeface.MONOSPACE);
          messageView.setGravity(gravity);
        }
      }
    

    呼叫显示消息工作来源MainActivity,其中Context通过是this.

    我想我不该打电话显示消息从我的内燃机但是我想知道怎么称呼它。 也就是说,什么上下文我应该通过吗?

    第一个论点是显示消息,我试过了,请getApplicationContext(),请getApplication(),请getApplication().getApplicationContext(),和getBaseContext().全部返回以下错误。我甚至提供了一个听众而不是null作为builder.setpositivebutton的第二个参数。相同错误:

    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
    

    下面是调试跟踪的一部分的打印屏幕。

    3 回复  |  直到 8 年前
        1
  •  1
  •   Anatolii    8 年前

    一般来说,Android Service Activity BroadcastReceiver

    服务 活动 Android Service Broadcast 发送信息 广播接收机

    定义 BROADCAST_FILTER 以便 可以确定消息意图来自服务:

    public static String BROADCAST_FILTER = <Your service class>.class.getName();
    

    以下内容:

    //send a broadcast intent from your service
    Intent intent = new Intent();
    intent.setAction(BROADCAST_FILTER);
    intent.putExtra("message", "<your message here>")
    sendBroadcast(intent);
    

    在你的

    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);
    }
    
        2
  •  1
  •   Vijendra patidar    8 年前

    您应该为这个错误使用活动上下文,我希望能解决这个错误。

    context=this;//并使用此上下文

        3
  •  0
  •   DSlomer64    8 年前

    因为我的应用程序的性质,我已经有了 BroadcastManager BroadcastReceiver 在问我问题之前,我已经做了一个很弱的尝试,类似于@user805311的建议。

    showMessage 在一个 IntentService

    publishProgress 对于 QueryDb if progress )通过另一个 Intent 导致异常,并立即通过 onPostExecute

    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);
    

    MatchesActivity 保养

    显示消息

    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
    

    显示消息 Context 显示消息 onActivityResult MainActivity ,它也在那里工作 收到并处理取消的“坏消息”时:

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

    显示消息 --它不把活动扩展到 主要活动 .

    推荐文章