简体   繁体   中英

Android setOnKeyListener causing ANR (Application Not Responding) prompt

I made a simple app that goes through all lines of a large (1.5MB) text file and displays each line that contains a specific word (the word is received from the user via an EditText). The app definitely puts my device under a lot of strain while it's searching through the text file but I had never received a single ANR prompt until I added the code below. Now I receive the ANR prompts often. Removing the code from the app gets rid of the ANR prompts. What is it about this code that could be causing the prompts? Is it written incorrectly? Aside from causing the ANR prompts, it's working properly.

editText1.setOnKeyListener(new EditText.OnKeyListener() 
{
   public boolean onKey(View v, int keyCode, KeyEvent event)
   {
      if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER))
      {
      button1.performClick();
      return true;
      }
   return false;
   }
});

EDIT:

It appears the ANR prompt was a result of the OnKeyListener process not being able to complete within a few seconds of being triggered via an Enter key press. It wasn't able to complete because it launched a time-consuming resource-hogging process that delayed its completion. The solution was to just have the OnKeyListener process change the value of a variable, instead of launching the resource-hogging process. This allows the OnKeyListener process to complete right away, then the resource-hogging process is launched from elsewhere (triggered by change in the variable's value).

Below, is the code I'm now using. At a later date, I'll try making a second app that puts the resource-hogging process in the background as recommended by Simon André Forsberg below.

   final Handler mHandler = new Handler();
   new Thread(new Runnable()
   {
   @Override
   public void run()
   {
      while (true) 
      {
         try 
         {
         mHandler.post(new Runnable() {
         @Override
            public void run()
            {
               if (NeedToClickButton == 1)
               {
               NeedToClickButton = 0
               button1.performClick();
               }
            }   
         });
      } catch (Exception e) {
   }}}}).start();



editText1.setOnKeyListener(new EditText.OnKeyListener() 
{
   public boolean onKey(View v, int keyCode, KeyEvent event)
   {
      if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER))
      {
      NeedToClickButton = 1;
      return true;
      }
   return false;
   }
});

You should be performing such long operations in an AsyncTask

Here's an example of how I would have done it:

class ScanTextTask extends AsyncTask<String, Void, List<String>> {
     protected List<String> doInBackground(String... param) {
         // load file from the string param[0]
         // add all the results to a list and return the list
     }

     protected void onPostExecute(List<String> result) {
         // add the result to the UI of your choice
     }
 }

And then, to start the task you use: new ScanTextTask().execute(filename);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM