如何让方法暂停并等待Android的输入?

时间:2010-10-26 13:10:56

标签: java android onclick buttonclick blackjack

基本上我已经创建了一个Blackjack应用程序,该应用程序使用了几种被调用的方法并传递了所需的信息(关于卡片和动作)。我在屏幕上显示了2个可点击的按钮(点击和站立)。现在我有一个叫做玩家转向的方法...这就是当我(通过静态整数)有选择按钮时,会发生一些事情。但是我用无限循环来做这个,认为它会继续检查按钮是否被按下然后只按下按钮时动作。这不起作用,因为我的屏幕在每次textview或imageview更改后都没有刷新,因此一旦我点击开始游戏,游戏就会“冻结”(由于方法永远不会结束),因此我无法点击所述按钮。有没有办法在android中调用类似于键盘监听器的东西(暂停活动并等待用户输入)?如果没有,你会建议解决方法是什么?最后(虽然不是当前重要的)如何在每次更改后如何正确刷新所有内容(我相信我需要使用invalidate ..虽然我不知道在invalidate之前有什么,所以它刷新整个事情)?先谢谢了。

5 个答案:

答案 0 :(得分:1)

看起来像是新的Activity(由startActivityForResult调用),而Handler(来自onActivityResult)可以解决您的问题。

看一下下面的设计片段:

activity interactions

假设您愿意“睡觉”的方法是来自doSomething类的MainActivity。我假设这是从一些事件处理程序实现调用的。您应该将该方法的所有调用移动到BackgroundActivity活动中, - 应显示ProgressDialog和/或其他内容 - 。
在doSomething方法中,您应该通过使用

指向BackgroundActivity的intent来启动活动
this.startActivityForResult(new Intent(this, BackgroundActivity.class), 
    BG_ACTIVITY_ID);

其中BG_ACTIVITY_ID是已启动活动的唯一标识符,因此当它完成时,您可以处理它。

processBackgroundData内(或当后台活动完成处理时),您应该在调用finish()之前设置结果:

final Intent intent = new Intent();
intent.putExtra(KEY_FOR_DATA_YOU_NEED, dataYouNeed);
setResult(Activity.RESULT_OK, intent);
finish();

在您的MainActivity中,您还应该覆盖onActivityResult方法,以从完成的BackgroundActivity任务中检索必要的信息:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    //you might also want to check if the resultCode is `Activity.RESULT_OK`...
    switch (requestCode)
    {
        case BG_ACTIVITY_ID:
            //get the data you need 
            final String dataYouNeed = data.getStringExtra(KEY_FOR_DATA_YOU_NEED);
            //process the data...
            //if necessary (threads!), call your backgroundHandler's 
            //sendMessage with the retrieved informations as obj.parameters
        [...]
            break;
        default:
            [...]
            break;
    }
}

在你的BackgroundHandler的{​​{1}}方法中(因为你回到了ui线程:运行主应用程序的线程)你可以做所有必要的ui修改,还有倾听用户事件。

这样你就可以摆脱无限循环,并且可以随时了解用户的互动。

答案 1 :(得分:1)

活动回调例程最后一个事件监听器的WAIT ... 这可能是一个简单的解决方案吗?

这个“等待用户输入”问题是一个经常出现的问题,也让我感到困惑,而且我还没有看到像我这样的真正干净的解决方案。

我最近提出了一个想法,但我在Android游戏中非常环保,我想看看它是如何经得起审查的。

该技术基于这样的想法:只要有一个事件监听器继续监听,活动回调例程就不会完成。结果,回调例程执行最后一个语句,然后什么也不做,但不结束。 (IOW,“你可以随时查看,但你永远不能离开....直到事件听众让你。”Yuk。)

这似乎符合要求。 UI未冻结且没有无限循环。用户界面的唯一要求是它支持事件列表。当用户提供输入时,事件回调例程(即onKey)处理输入,然后在需要NEXT用户输入之前执行所有步骤。然后事件回调例程设置一个新的监听器并返回,释放旧的监听器,并让UI保留一个任务 - 维持新的监听器。这将继续迭代,直到活动回调例程完成。

以下是我测试的一些代码:

@Override   
    public void onCreate(Bundle savedInstanceState) {       
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main);
    }

         public void onStart() {
           super.onStart();

        final EditText et = (EditText) findViewById(R.id.edittext);
        et.setOnKeyListener(new OnKeyListener() {    
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                    boolean tf = checKey(keyCode, event);
                    if(tf==false)return false;
                    gotPW();
                    return true;
            }
        });
    }


         gotPW(){
               ...do ALL the stuff you want to do before you need more user input
               ...set ANOTHER event listener that is connected to another 
                  event callback method

               ...return, releasing the first event listener, and putting the onStart 
                  routine back in its same state -- nothing to do except to attend to 
                  an event listener.
         }



         //this checks to see if the enter key has been hit
         public boolean checKey(int keyCode, KeyEvent event){   
       if ((event.getAction() == KeyEvent.ACTION_DOWN) && 
                (keyCode == KeyEvent.KEYCODE_ENTER)) 
    {          
        return true;        
    }        
    return false;    
}

前面的代码似乎做了所需要的...... onStart等待我的输入。

这是一项好技术吗?

我有没有发现问题?

大家一直这样做, 只有像我这样的新手认为他们正在做些什么?

答案 2 :(得分:0)

Android会为你运行一个事件循环 - 所以你不必自己循环等待输入。

您可以通过多种方式挂钩循环。从1.6开始,最简单的方法是在XML中指定钩子,例如:

<按钮android:onClick =“myClickHandler”/>

或者,您可以通过调用setOnClickListener在代码中执行此操作。

看看http://android-developers.blogspot.com/2009/10/ui-framework-changes-in-android-16.html的一些例子(阅读“更容易点击听众”一节)

如果您可以在视图中失效,那么Android事件循环将负责重新绘制屏幕,​​包括任何布局更改。如果您有自定义View,则会根据需要调用它们的onDraw()。

希望这有帮助。

答案 3 :(得分:0)

我可能有错误的解释,但似乎做setOnClickListener有它,以便当达到代码的某一部分时,按钮变为可点击并在单击按钮时采取行动?我已经拥有它,以便当点击一个按钮并且播放器转动时,将发生动作。然而,我需要知道的是如何让程序真正等待或暂停,直到按下其中一个按钮。

类似于当你煽动键盘并且java等待键盘输入时。

答案 4 :(得分:0)

不要轮询以查看您的按钮是否已被按下。只需在OnClickHandler中执行您想要的任何操作。

以下是您的代码可能类似的示例(错误方式):

while(1) {
  if (buttonHitClicked()) {
    doHit();
  } else if (buttonStandClicked()) {
    doStand();
  }
  //sleep(); // won't help
}

这是正确的方法:

OnClickListener hitListener = new OnClickListener() {
  public void onClick(View v) { doHit(); }
};
OnClickListener standListener = new OnClickListener() {
  public void onClick(View v) { doStand(); }
};

protected void OnCreate(Bundle savedValues) {
  ...

  Button hitButton = (Button)findViewById(R.id.hitButton);
  button.setOnClickListener(hitListener);

  Button standButton = (Button)findViewById(R.id.standButton);
  button.setOnClickListener(standListener);

  ...
}

是的,正确的方式涉及更多的打字......但它也工作。如果你看一下Collin发布的链接,就会有一种“类型为y”的方式来做这件事,包括在AndroidManifest文件中添加内容。您只需将其指向具有正确签名的类中的函数(我记得public void funcName(View v)),Android就会为您处理所有侦听器内容。

就“让你的程序等待”而言,已经是。在对某个类的入口点进行某些调用之前,您的程序代码才会运行。在此之前,执行在您的进程中的Android UI处理程序代码中浮动,来回传递消息。只要其中一条消息最终出现在您的应用程序中(onCreate,一个点击监听器等),您的代码就会执行并返回,允许该UI线程返回处理应用程序进程的所有输入。

如果您的应用需要超过5秒左右的时间才能响应消息,系统会将其杀死,并显示“ANR”... App Not Responding。

Another handy Google IO video名为“编写Zippy Android应用”。