我正在创建一个使用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$DecorView@40594188 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
com.android.internal.policy.impl.PhoneWindow$DecorView@40594188 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();
}
}
}
}
答案 0 :(得分:0)
引起:java.lang.RuntimeException:无法在里面创建处理程序 没有调用Looper.prepare()的线程09-18 10:55:40.456: E / AndroidRuntime(3273):at android.os.Handler。(Handler.java:121)09-18 10:55:40.456: E / AndroidRuntime(3273):at android.widget.Toast 。(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)
您在doInBackground()
内呼叫 Toast 。 doInBackground()在非ui线程上运行,你不能在其中执行UI功能。
所以,不要在doInBackGround()内部任何东西,在那里设置一个标志,当你来到onPostExecute()时,检查那个标志的值,并在必要时制作Toast。
答案 1 :(得分: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
是我创建的类。如果您想从Activity
开始新的asyncTask
,只需创建一个新Intent
并从onPostExecute
答案 2 :(得分: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
您可以在异步任务中添加一个简单的构造函数,而不是为不同的服务器名称创建另一个任务类。