2012-09-20 109 views
0

我正在创建一个使用api发送短信的android应用程序。当我尝试取消异步任务并开始另一个任务时,我面临强制关闭问题。我想要做的是,如果邮件没有在5秒内发送进度对话框应该消失,异步任务应该取消,并且应该开始新的任务。我已经为此写了一个代码。请帮我解决这个错误。如何取消异步任务

09-18 10:55:40.456: E/AndroidRuntime(3273): FATAL EXCEPTION: AsyncTask #1 
09-18 10:55:40.456: E/AndroidRuntime(3273): java.lang.RuntimeException: An error 
occured while executing doInBackground() 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
android.os.AsyncTask$3.done(AsyncTask.java:200) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
java.util.concurrent.FutureTask.run(FutureTask.java:138) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at java.lang.Thread.run(Thread.java:1019) 
09-18 10:55:40.456: E/AndroidRuntime(3273): Caused by: java.lang.RuntimeException: Can't create 
handler inside thread that has not called Looper.prepare() 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at android.os.Handler.<init>(Handler.java:121) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at android.widget.Toast.<init>(Toast.java:68) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at android.widget.Toast.makeText(Toast.java:231) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
com.widgets.application.MainActivity$sendMessageAsync.doInBackground(MainActivity.java:260) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
com.widgets.application.MainActivity$sendMessageAsync.doInBackground(MainActivity.java:1) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
android.os.AsyncTask$2.call(AsyncTask.java:185) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  at 
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
09-18 10:55:40.456: E/AndroidRuntime(3273):  ... 4 more 
09-18 10:55:43.432: E/WindowManager(3273): Activity com.widgets.application.MainActivity has leaked 
window com.android.internal.policy.impl.PhoneWindow$Dec[email protected] that was originally added here 
09-18 10:55:43.432: E/WindowManager(3273): android.view.WindowLeaked: Activity 
com.widgets.application.MainActivity has leaked window 
[email protected] that was originally added here 
09-18 10:55:43.432: E/WindowManager(3273): at android.view.ViewRoot.<init>(ViewRoot.java:258) 
09-18 10:55:43.432: E/WindowManager(3273): at 
android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 
09-18 10:55:43.432: E/WindowManager(3273): at 
android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 
09-18 10:55:43.432: E/WindowManager(3273): at 
android.view.Window$LocalWindowManager.addView(Window.java:424) 
09-18 10:55:43.432: E/WindowManager(3273): at android.app.Dialog.show(Dialog.java:241) 
09-18 10:55:43.432: E/WindowManager(3273): at 
android.app.ProgressDialog.show(ProgressDialog.java:107) 
09-18 10:55:43.432: E/WindowManager(3273): at 
android.app.ProgressDialog.show(ProgressDialog.java:90) 
09-18 10:55:43.432: E/WindowManager(3273): at 
com.widgets.application.MainActivity.onClick(MainActivity.java:331) 
09-18 10:55:43.432: E/WindowManager(3273): at android.view.View.performClick(View.java:2485) 
09-18 10:55:43.432: E/WindowManager(3273): at android.view.View$PerformClick.run(View.java:9080) 
09-18 10:55:43.432: E/WindowManager(3273): at android.os.Handler.handleCallback(Handler.java:587) 
09-18 10:55:43.432: E/WindowManager(3273): at android.os.Handler.dispatchMessage(Handler.java:92) 
09-18 10:55:43.432: E/WindowManager(3273): at android.os.Looper.loop(Looper.java:123) 
09-18 10:55:43.432: E/WindowManager(3273): at 
android.app.ActivityThread.main(ActivityThread.java:3683) 
09-18 10:55:43.432: E/WindowManager(3273): at java.lang.reflect.Method.invokeNative(Native Method) 
09-18 10:55:43.432: E/WindowManager(3273): at java.lang.reflect.Method.invoke(Method.java:507) 
09-18 10:55:43.432: E/WindowManager(3273): at 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
09-18 10:55:43.432: E/WindowManager(3273): at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
09-18 10:55:43.432: E/WindowManager(3273): at dalvik.system.NativeStart.main(Native Method) 

代码

public class MainActivity extends Activity implements OnPanelListener, OnClickListener, OnItemClickListener { 

final static int RQS_PICK_CONTACT = 1; 
public static String sendSmsToNumber = ""; 

private EditText editText, editUserName, editPassword; 
private ArrayList<Map<String, String>> mPeopleList; 
private SimpleAdapter mAdapter; 
private AutoCompleteTextView mTxtPhoneNo; 
private Panel bottomPanel; 
private Panel topPanel; 
private Button btnsend; 
private ProgressDialog pd; 
//private String gateway_name; 
private Spinner spinner1; 
Context context; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    editUserName = (EditText) findViewById(R.id.editTextUserName); 
    editPassword = (EditText) findViewById(R.id.editTextPassword); 
    mTxtPhoneNo = (AutoCompleteTextView) findViewById(R.id.mmWhoNo); 
    mTxtPhoneNo.setTextColor(Color.BLACK); 
    editText = (EditText) findViewById(R.id.editTextMessage); 
    spinner1 = (Spinner) findViewById(R.id.spinnerGateway); 
    btnsend = (Button) findViewById(R.id.btnSend); 
    btnsend.setOnClickListener(this); 
    mPeopleList = new ArrayList<Map<String, String>>(); 
    PopulatePeopleList(); 
    mAdapter = new SimpleAdapter(this, mPeopleList, R.layout.custcontview, 
      new String[] { "Name", "Phone", "Type" }, new int[] { 
        R.id.ccontName, R.id.ccontNo, R.id.ccontType }); 
    mTxtPhoneNo.setAdapter(mAdapter); 
    mTxtPhoneNo.setOnItemClickListener(this); 
    Button buttonPickContact = (Button) findViewById(R.id.btnContact); 
    buttonPickContact.setOnClickListener(new Button.OnClickListener() { 
     public void onClick(View arg0) { 
      Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
      intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); 
      startActivityForResult(intent, RQS_PICK_CONTACT); 
     } 
    });  
    init(); 
    Panel panel; 
    topPanel = panel = (Panel) findViewById(R.id.mytopPanel); 
    panel.setOnPanelListener(this); 
    panel.setInterpolator(new BounceInterpolator(Type.OUT)); 

} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
    super.onActivityResult(requestCode, resultCode, data);   
     if(requestCode == RQS_PICK_CONTACT){ 
      if(resultCode == RESULT_OK){ 
       Uri contactData = data.getData(); 
       Cursor cursor = managedQuery(contactData, null, null, null, null); 
       cursor.moveToFirst(); 
       String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 
       String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
       sendSmsToNumber = number; 
       trimContactNumber(); 
       mTxtPhoneNo.setText(name + " <" + number + ">"); 
      } 
     } 
} 

public void trimContactNumber() { 
    sendSmsToNumber = sendSmsToNumber.replace("-", ""); 
    sendSmsToNumber = sendSmsToNumber.replace("+91", ""); 
    if(sendSmsToNumber.length() > 10){ 
     sendSmsToNumber = sendSmsToNumber.substring(1, sendSmsToNumber.length()); 
    } 
} 

public void PopulatePeopleList() { 
    mPeopleList.clear(); 
    Cursor people = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); 
    while (people.moveToNext()) { 
     String contactName = people.getString(people.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 
     String contactId = people.getString(people.getColumnIndex(ContactsContract.Contacts._ID)); 
     String hasPhone = people.getString(people.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)); 

     if ((Integer.parseInt(hasPhone) > 0)) { 
      Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
        null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null); 
      while (phones.moveToNext()) { 
       String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
       String numberType = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); 
       Map<String, String> NamePhoneType = new HashMap<String, String>(); 
       NamePhoneType.put("Name", contactName); 
       NamePhoneType.put("Phone", phoneNumber); 
       if (numberType.equals("0")) 
        NamePhoneType.put("Type", "Work"); 
       else if (numberType.equals("1")) 
        NamePhoneType.put("Type", "Home"); 
       else if (numberType.equals("2")) 
        NamePhoneType.put("Type", "Mobile"); 
       else 
        NamePhoneType.put("Type", "Other"); 
       mPeopleList.add(NamePhoneType); 
      } 
      phones.close(); 
     } 
    } 
    people.close(); 
    startManagingCursor(people); 
} 

public void onItemClick(AdapterView<?> av, View arg1, int index, long arg3) { 
    @SuppressWarnings("unchecked") 
    Map<String, String> map = (Map<String, String>) av.getItemAtPosition(index); 
    String name = map.get("Name"); 
    String number = map.get("Phone"); 
    mTxtPhoneNo.setText(name + " <" + number + ">"); 
    sendSmsToNumber = number; 
    trimContactNumber(); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

private void init() { 
    editUserName = (EditText) findViewById(R.id.editTextUserName); 
    editPassword = (EditText) findViewById(R.id.editTextPassword); 
    readPerson(); 
} 

public void reset(View view) { 
    PreferenceConnector.getEditor(this).remove(PreferenceConnector.NAME).commit(); 
    PreferenceConnector.getEditor(this).remove(PreferenceConnector.SURNAME).commit(); 
    PreferenceConnector.getEditor(this).remove(PreferenceConnector.AGE).commit(); 
    readPerson(); 
} 

private void readPerson() { 
    editUserName.setText(PreferenceConnector.readString(this, 
      PreferenceConnector.NAME, null)); 
    editPassword.setText(PreferenceConnector.readString(this, 
      PreferenceConnector.SURNAME, null)); 
} 

public void save(View view) { 
    String userNameTxt = editUserName.getText().toString(); 
    String PasswdTxt = editPassword.getText().toString(); 

    if (userNameTxt != null) 
     PreferenceConnector.writeString(this, PreferenceConnector.NAME,userNameTxt); 
    if (PasswdTxt != null) 
     PreferenceConnector.writeString(this, PreferenceConnector.SURNAME,PasswdTxt); 

} 

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_T) { 
     topPanel.setOpen(!topPanel.isOpen(), false); 
     return false; 
    } 
    if (keyCode == KeyEvent.KEYCODE_B) { 
     bottomPanel.setOpen(!bottomPanel.isOpen(), true); 
     return false; 
    } 
    return super.onKeyDown(keyCode, event); 
} 

public void onPanelClosed(Panel panel) { 
    String panelName = getResources().getResourceEntryName(panel.getId()); 
    Log.d("TestPanels", "Panel [" + panelName + "] closed"); 
} 

public void onPanelOpened(Panel panel) { 
    String panelName = getResources().getResourceEntryName(panel.getId()); 
    Log.d("TestPanels", "Panel [" + panelName + "] opened"); 
} 

public boolean isOnline() { 
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo netInfo = cm.getActiveNetworkInfo(); 
    if (netInfo != null && netInfo.isConnectedOrConnecting()) { 
     return true; 
    } 
    return false; 
} 

public boolean isValid() { 
    if (editUserName.getText().length() == 10 && editPassword.getText().length() != 0 && sendSmsToNumber.length() >= 10 && editText.getText().length() != 0) { 
     return true; 
    } 
    return false; 
} 

private class sendMessageAsync extends AsyncTask<Void, Void, String>{ 
    String resultSet; 

    @Override 
    protected void onPreExecute(){ 
    } 

    @Override 
    protected String doInBackground(Void... arg0) { 
     String usrname = editUserName.getText().toString(); 
     String usrPassword = editPassword.getText().toString(); 
     String number = sendSmsToNumber; 
     String message = editText.getText().toString(); 
     String gateway_name = String.valueOf(spinner1.getSelectedItem()); 
     String gatewayToUse = gateway_name; 
     Log.i("Gateway", String.valueOf(spinner1.getSelectedItem())); 
     String msgreciever = number; 
     String testMessage = message; 
     try{ 
      SmsSender.sendMessage(msgreciever, testMessage, usrname,usrPassword, gatewayToUse); 
      resultSet = SmsSender.toastText; 
      timerDelayRemoveDialog(5000, pd);    

     } catch(Exception ex){ 
      Toast.makeText(MainActivity.this,"Error",Toast.LENGTH_SHORT).show(); 
     } 
     return resultSet; 
    } 

    @Override 
    protected void onPostExecute(String result){ 
     //super.onPostExecute(result); 
     pd.dismiss(); 
     Toast.makeText(MainActivity.this,resultSet,Toast.LENGTH_SHORT).show(); 
    } 

} 

public void timerDelayRemoveDialog(long time, final Dialog d){ 
    new Handler().postDelayed(new Runnable() { 
     public void run() { 
      sendMessageAsync sma = new sendMessageAsync(); 
      sma.cancel(true); 
      d.dismiss(); 
      Toast.makeText(MainActivity.this,"Sending Failed. Using Backup Server. Please Wait..",Toast.LENGTH_SHORT).show(); 
      sendBackupMessageAsync sbma = new sendBackupMessageAsync(); 
      sbma.execute(); 
     } 
    }, time); 
} 

private class sendBackupMessageAsync extends AsyncTask<Void, Void, String>{ 
    String resultSet; 

    @Override 
    protected void onPreExecute(){ 
    } 

    @Override 
    protected String doInBackground(Void... arg0) {   
     String usrname = editUserName.getText().toString(); 
     String usrPassword = editPassword.getText().toString(); 
     String number = sendSmsToNumber; 
     String message = editText.getText().toString(); 
     String gateway_name = String.valueOf(spinner1.getSelectedItem()); 
     String gatewayToUse = gateway_name; 
     Log.i("Gateway", String.valueOf(spinner1.getSelectedItem())); 
     String msgreciever = number; 
     String testMessage = message; 
     try{ 
      BackupSender.sendMessage(msgreciever, testMessage, usrname,usrPassword, gatewayToUse); 
      resultSet = BackupSender.toastText; 
     } catch(Exception ex){ 
      Toast.makeText(MainActivity.this,"Error",Toast.LENGTH_SHORT).show(); 
     } 
     return resultSet; 
    } 

    @Override 
    protected void onPostExecute(String result){ 
     //super.onPostExecute(result); 
     pd.dismiss(); 
     Toast.makeText(MainActivity.this,resultSet,Toast.LENGTH_SHORT).show(); 
    } 

} 

public void onClick(View v) { 
    if (v == btnsend){ 
     if (!isOnline()){ 
      Toast.makeText(MainActivity.this,"No Internet Access..Cannot Send SMS",Toast.LENGTH_SHORT).show(); 
     } else if (!isValid()){ 
      Toast.makeText(MainActivity.this,"All fields are required. Try Again.",Toast.LENGTH_SHORT).show(); 
     } else { 
      save(v); 
      pd.setCancelable(true); 
      pd = ProgressDialog.show(MainActivity.this, "Free Sms","Sending SMS. Please Wait", true); 
      sendMessageAsync sma = new sendMessageAsync(); 
      sma.execute(); 
     } 
    } 
} 
} 
+1

我觉得问题是Toast消息。从Asynctask中删除Toast消息,看看有什么happns。 –

+0

@ChiragRaval你看到代码中的任何其他问题? –

回答

0

产生的原因:了java.lang.RuntimeException:无法创建 线程已经不叫Looper.prepare()09-18 10:55内部处理程序: 40.456: E/AndroidRuntime(3273):在 android.os.Handler(Handler.java:121)10月9日至18日:55:40.456: E/AndroidRuntime(3273):在 android.widget.Toast。(Toast.java:68)09-18 10:55: 40.456: E/AndroidRuntime(3273):在 android.widget。 Toast.makeText(Toast.java:231)09-18 10:55:40.456: E/AndroidRuntime(3273):at com.widgets.application.MainActivity $ sendMessageAsync。 doInBackground(MainActivity.java:260)

要调用吐司doInBackground()内。 doInBackground()在非UI用户线程上运行,并且不能在其中执行UI功能。

因此,不是在doInBackGround()内部烘烤任何东西,而是在那里设置一个标志,当你来到onPostExecute()时,检查该标志的值并在必要时进行烘烤。

+0

武力接近的原因是什么? –

+0

“吐司”声明。 – Swayam

+0

哪Toast语句创建错误?你可以在日志中看到关于并发错误的内容。 –

0

您必须在您的asyncTask中实现onPostExcute方法。此方法应该照顾UI更新。例如:

protected void onPostExecute(Object result) { 
     if (pd != null) 
      pd.cancel(); 

     if (result.equals("1")) { 

      Toast.makeText(getApplicationContext(), 
        "The log file has been sent", Toast.LENGTH_LONG).show(); 

      Intent j = new Intent(SendLogDialog.this, MyClass.class); 
      startActivity(j); 
     } 

     else if (result.equals("2")) { 

      new ErrorDialog(getApplicationContext(), "File doesn't exist", 
        "The log file doesn't exist, can't send mail", 
        "Show Settings", 1); 
     } 

     else if (result.equals("3")) { 
      new ErrorDialog(getApplicationContext(), 
        "Error sending log file", 
        "The log file could not be sent, please try again", 
        "Ok", 5); 
     } 

    } 

这是我如何显示用户是否出事了日期的处理在doInBackground方法的例子。请注意,ErrorDialog是我创建的类。如果你想从asyncTask开始新Activity简单地做出一个新的Intent并开始从onPostExecute

0

代码的活动需要进行重构,以达到抵消作用。 当您想取消与中断异步任务,您可以拨打:

yourtask.cancel(true); 

内,您的doInBackground方法,你需要检查它是否被取消或不通过调用isCancelled(),以尽快停止。取消操作后,它不会在您的异步任务中调用onPostExecute方法。

如果你想指定一个超时,你不应该把它放在的doInBackground方法中。你想调用异步方法,然后用超时调用第二个方法来取消以前的调用。

final MessageAsyncTask yourtask = new MessageAsyncTask(); 
yourtask.execute(); 
yourTimerDelayActiontoExecuteLater(5000, yourtask, d); // this will send cancel if finished flag is not set from async task 

您可以在异步任务中添加一个简单构造函数,以便不为另一个服务器名称创建另一个任务类。