2014-04-07 25 views
0

我被指示使用AsyncTask,因为多线程仍然导致我的应用程序冻结。我不相信我正确使用AsyncTask。在示例中,我在线看到,他们不必调用方法Complete()使用executeOnExcecutor的AsyncTask使用太多的内存并导致UI冻结

http://examples.javacodegeeks.com/android/core/os/asynctask/android-asynctask-example/

我打电话的情况下READ_MESSAGE Complete()并预期它崩溃了我的申请。我不知道我需要采取哪些步骤来修复此代码。使用executeOnExcecutor的AsyncTask使用太多内存并导致UI冻结。我相信我不正确地调用'Complete()'。

BluetoothChat全码

/** 
* This is the main Activity that displays the current chat session. 
*/ 
@SuppressLint("HandlerLeak") 
public class BluetoothChat extends Activity { 
    // Debugging 
    private static final String TAG = "BluetoothChat"; 
    private static final boolean D = true; 

    // Message types sent from the BluetoothChatService Handler 
    public static final int MESSAGE_STATE_CHANGE = 1; 
    public static final int MESSAGE_READ = 2; 
    public static final int MESSAGE_WRITE = 3; 
    public static final int MESSAGE_DEVICE_NAME = 4; 
    public static final int MESSAGE_TOAST = 5; 
    public static final int THREAD_POOL_SIZE = Integer.MAX; 

    // Key names received from the BluetoothChatService Handler 
    public static final String DEVICE_NAME = "device_name"; 
    public static final String TOAST = "toast"; 

    // Intent request codes 
    private static final int REQUEST_CONNECT_DEVICE_SECURE = 1; 
    private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2; 
    private static final int REQUEST_ENABLE_BT = 3; 

    // Layout Views 
    private ListView mConversationView; 
    private EditText mOutEditText; 
    private Button mSendButton; 
    public Button mFunctionButton; 
    public Button seizureResult; 
    public double [][]stored = new double[8000][1]; 
    public static HjorthClass finalValue; 
    public int a; 
    public Handler handler; 
    public static boolean potato = false; 
    public String transfer; 
    public boolean bool; 

    // Name of the connected device 
    private String mConnectedDeviceName = null; 
    // Array adapter for the conversation thread 
    private ArrayAdapter<String> mConversationArrayAdapter; 
    // String buffer for outgoing messages 
    private StringBuffer mOutStringBuffer; 
    // Local Bluetooth adapter 
    private BluetoothAdapter mBluetoothAdapter = null; 
    // Member object for the chat services 
    private BluetoothChatService mChatService = null; 


    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     getWindow().requestFeature(Window.FEATURE_ACTION_BAR); 
     if(D) Log.e(TAG, "+++ ON CREATE +++"); 

     // Set up the window layout 
     setContentView(R.layout.main); 
     setTitle("Seizure Detection Helmet Application"); 

     handler = new Handler(); 
     mFunctionButton = (Button)findViewById(R.id.functions); 
     seizureResult = (Button)findViewById(R.id.SeizureResult); 

     mFunctionButton.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 

       Intent z = new Intent(BluetoothChat.this, MainActivity.class); 
       startActivity(z); 
      } 

     }); 
     seizureResult.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v){ 
       Toast.makeText(getApplicationContext(), "Value =="+bool, Toast.LENGTH_LONG).show(); 
     } 
     }); 

     // Get local Bluetooth adapter 
     mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 

     // If the adapter is null, then Bluetooth is not supported 
     if (mBluetoothAdapter == null) { 
      Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show(); 
      finish(); 
      return; 
     } 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     if(D) Log.e(TAG, "++ ON START ++"); 

     // If BT is not on, request that it be enabled. 
     // setupChat() will then be called during onActivityResult 
     if (!mBluetoothAdapter.isEnabled()) { 
      Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivityForResult(enableIntent, REQUEST_ENABLE_BT); 
     // Otherwise, setup the chat session 
     } else { 
      if (mChatService == null) setupChat(); 
     } 
    } 

    @Override 
    public synchronized void onResume() { 
     super.onResume(); 
     if(D) Log.e(TAG, "+ ON RESUME +"); 

     // Performing this check in onResume() covers the case in which BT was 
     // not enabled during onStart(), so we were paused to enable it... 
     // onResume() will be called when ACTION_REQUEST_ENABLE activity returns. 
     if (mChatService != null) { 
      // Only if the state is STATE_NONE, do we know that we haven't started already 
      if (mChatService.getState() == BluetoothChatService.STATE_NONE) { 
       // Start the Bluetooth chat services 
       mChatService.start(); 
      } 
     } 
    } 

    private void setupChat() { 
     Log.d(TAG, "setupChat()"); 

     // Initialize the array adapter for the conversation thread 
     mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message); 
     mConversationView = (ListView) findViewById(R.id.in); 
     mConversationView.setAdapter(mConversationArrayAdapter); 

     // Initialize the compose field with a listener for the return key 
     mOutEditText = (EditText) findViewById(R.id.edit_text_out); 
     mOutEditText.setOnEditorActionListener(mWriteListener); 

     // Initialize the send button with a listener that for click events 
     mSendButton = (Button) findViewById(R.id.button_send); 
     mSendButton.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 
       // Send a message using content of the edit text widget 
       TextView view = (TextView) findViewById(R.id.edit_text_out); 
       String message = view.getText().toString(); 
       sendMessage(message); 
      } 
     }); 

     // Initialize the BluetoothChatService to perform bluetooth connections 
     mChatService = new BluetoothChatService(this, mHandler); 

     // Initialize the buffer for outgoing messages 
     mOutStringBuffer = new StringBuffer(""); 
    } 

    @Override 
    public synchronized void onPause() { 
     super.onPause(); 
     if(D) Log.e(TAG, "- ON PAUSE -"); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     if(D) Log.e(TAG, "-- ON STOP --"); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     // Stop the Bluetooth chat services 
     if (mChatService != null) mChatService.stop(); 
     if(D) Log.e(TAG, "--- ON DESTROY ---"); 
    } 

    private void ensureDiscoverable() { 
     if(D) Log.d(TAG, "ensure discoverable"); 
     if (mBluetoothAdapter.getScanMode() != 
      BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { 
      Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 
      discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); 
      startActivity(discoverableIntent); 
     } 
    } 

    private class ProcessData extends AsyncTask<Boolean, Void, Boolean> 
    { 

     @Override 
     protected Boolean doInBackground(Boolean... params) 
     { 
     for(int a = 0; a<8000; a++) 
     { 
      try 
      { 
      if(transfer == null) 
      { 
       transfer = "0"; 
      } 
      double[] convert = new double[1]; 
      for(int z=0; z <1;z++) 
      { 
      convert[z]= Double.parseDouble(transfer); 
      } 
      for(int j=0; j<1;j++) 
      { 
      stored[a][j]= convert[j]; 
      } 
      } 
      catch(NumberFormatException e) 
      { 
      } 
      } 
      finalValue = new HjorthClass(stored); 
      bool = finalValue.returnSum(); 
      return bool; 
     } 
    } 

    private final ExecutorService mThreadPoolExecutor = Executors.newFixedThreadPool(THREAD_POOL_SIZE); 

    public void Complete() 
    { 
     ProcessData task = new ProcessData(); 
     task.executeOnExecutor(mThreadPoolExecutor,bool); 
    } 


    /** 
    * Sends a message. 
    * @param message A string of text to send. 
    */ 
    private void sendMessage(String message) { 
     // Check that we're actually connected before trying anything 
     if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) { 
      Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show(); 
      return; 
     } 

     // Check that there's actually something to send 
     if (message.length() > 0) { 
      // Get the message bytes and tell the BluetoothChatService to write 
      byte[] send = message.getBytes(); 
      mChatService.write(send); 

      // Reset out string buffer to zero and clear the edit text field 
      mOutStringBuffer.setLength(0); 
      mOutEditText.setText(mOutStringBuffer); 
     } 
    } 

    // The action listener for the EditText widget, to listen for the return key 
    private TextView.OnEditorActionListener mWriteListener = 
     new TextView.OnEditorActionListener() { 
     public boolean onEditorAction(TextView view, int actionId, KeyEvent event) { 
      // If the action is a key-up event on the return key, send the message 
      if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) { 
       String message = view.getText().toString(); 
       sendMessage(message); 
      } 
      if(D) Log.i(TAG, "END onEditorAction"); 
      return true; 
     } 
    }; 




    /** private final void setStatus(int resId) { 
     final ActionBar actionBar = getActionBar(); 
     actionBar.setSubtitle(resId); 
    } 

    private final void setStatus(CharSequence subTitle) { 
     final ActionBar actionBar = getActionBar(); 
     actionBar.setSubtitle(subTitle); 
    } **/ 

    // The Handler that gets information back from the BluetoothChatService 
    private final Handler mHandler = new Handler() { 
     @Override 
     public void handleMessage(final Message msg) { 
      switch (msg.what) { 
      case MESSAGE_STATE_CHANGE: 
       if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); 
       switch (msg.arg1) { 
       case BluetoothChatService.STATE_CONNECTED: 
        //setStatus(getString(R.string.title_connected_to, mConnectedDeviceName)); 
        mConversationArrayAdapter.clear(); 
        break; 
       case BluetoothChatService.STATE_CONNECTING: 
        // setStatus(R.string.title_connecting); 
        break; 
       case BluetoothChatService.STATE_LISTEN: 
       case BluetoothChatService.STATE_NONE: 
        //setStatus(R.string.title_not_connected); 
        break; 
       } 
       break; 
      case MESSAGE_WRITE: 
       byte[] writeBuf = (byte[]) msg.obj; 
       // construct a string from the buffer 
       String writeMessage = new String(writeBuf); 
       mConversationArrayAdapter.add("Me: " + writeMessage); 
       break; 
      case MESSAGE_READ: 
      byte[] readBuf = (byte[]) msg.obj; 
       String readMessage = new String(readBuf,0,msg.arg1); 
       transfer = readMessage; 
       mConversationArrayAdapter.add("Voltage: "+ transfer); 
       Complete(); 
       break; 


      case MESSAGE_DEVICE_NAME: 
       // save the connected device's name 
       mConnectedDeviceName = msg.getData().getString(DEVICE_NAME); 
       Toast.makeText(getApplicationContext(), "Connected to " 
           + mConnectedDeviceName, Toast.LENGTH_SHORT).show(); 
       break; 
      case MESSAGE_TOAST: 
       Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), 
           Toast.LENGTH_SHORT).show(); 
       break; 
      } 
     } 
    }; 

    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if(D) Log.d(TAG, "onActivityResult " + resultCode); 
     switch (requestCode) { 
     case REQUEST_CONNECT_DEVICE_SECURE: 
      // When DeviceListActivity returns with a device to connect 
      if (resultCode == Activity.RESULT_OK) { 
       connectDevice(data, true); 
      } 
      break; 
     case REQUEST_CONNECT_DEVICE_INSECURE: 
      // When DeviceListActivity returns with a device to connect 
      if (resultCode == Activity.RESULT_OK) { 
       connectDevice(data, false); 
      } 
      break; 
     case REQUEST_ENABLE_BT: 
      // When the request to enable Bluetooth returns 
      if (resultCode == Activity.RESULT_OK) { 
       // Bluetooth is now enabled, so set up a chat session 
       setupChat(); 
      } else { 
       // User did not enable Bluetooth or an error occurred 
       Log.d(TAG, "BT not enabled"); 
       Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); 
       finish(); 
      } 
     } 
    } 

    private void connectDevice(Intent data, boolean secure) { 
     // Get the device MAC address 
     String address = data.getExtras() 
      .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); 
     // Get the BluetoothDevice object 
     BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 
     // Attempt to connect to the device 
     mChatService.connect(device, secure); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.option_menu, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     Intent serverIntent = null; 
     switch (item.getItemId()) { 
     case R.id.secure_connect_scan: 
      // Launch the DeviceListActivity to see devices and do scan 
      serverIntent = new Intent(this, DeviceListActivity.class); 
      startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE); 
      return true; 
     case R.id.insecure_connect_scan: 
      // Launch the DeviceListActivity to see devices and do scan 
      serverIntent = new Intent(this, DeviceListActivity.class); 
      startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE); 
      return true; 
     case R.id.discoverable: 
      // Ensure this device is discoverable by others 
      ensureDiscoverable(); 
      return true; 
     } 
     return false; 
    } 


} 
+0

为什么不使用onPostExecute()doInBackground(后实际触发),并返回从线程 – Saqib

+0

保护无效onPostExecute(布尔布尔)需要的结果{// 执行长耗时的操作 finalResult.setText(结果”布尔值“+ bool); }类似的东西? – SeniorDesignStudy

+0

'RejectedExecutionException:pool = 128/128,queue = 10/10'。它没有暗示你什么?发送消息的HjorthClass是? – Blackbelt

回答

0

看起来像我最初的回答太短,结果被转换成一个评论:(。因为它实际上是一个答案,而不是评论我粘贴它一次。

你创建了太多AsyncTasks和系统无法分配这么多线程同样的问题在这里回答:java.util.concurrent.RejectedExecutionException: pool=128/128, queue=10/10

+0

谢谢。现在的问题是我该如何解决这个问题? – SeniorDesignStudy

+0

您经常创建太多任务。这意味着在以前的人有时间完成之前,你正在开始其他人做同样的事情。我不知道你的用例,但我认为你可以忽略发送给处理程序的那些事件中的一些,因为处理无论如何是重叠的。也许可以忽略这些消息,除非自上一次接收消息以来已超过几秒钟? – azertiti

+0

您想发布完整的代码吗? – SeniorDesignStudy

0

RejectedExecutionException已通过队列的能力有限所致,它保持等待任务(而不是线程池的大小)。队列

默认容量为10

如果你想有更多的任务排队与executeOnExecutor代替execute运行它们(在Android> 3.0):

// create fixed-size thread pool for Executor 
private final ExecutorService mThreadPoolExecutor = 
    Executors.newFixedThreadPool(THREAD_POOL_SIZE); 

// then execute your task 
task.executeOnExecutor(mThreadPoolExecutor, bool); 

在这种情况下排队能力将等于Integer.MAX_VALUE而不是10,并且您不会拒绝任务(但请注意,不要用尽提交太多任务的内存)。

我还建议重命名您的Boolean bool变量,看起来很混乱。

+0

我的应用程序立即崩溃,我得到了错误java.lang.NoSuchMethod.I'm假设我的android不大于3.0 – SeniorDesignStudy

+0

有没有Android手机<3.0的任何解决方案? – SeniorDesignStudy

+0

你能否检查你的设备API? (设置 - >关于设备),以及什么是应用程序的'minSdkVersion'(在AndroidManifest.xml中)? – kiruwka