2012-09-20 6 views
0

api를 사용하여 SMS를 보내기위한 안드로이드 응용 프로그램을 만들고 있습니다. 비동기 작업을 취소하고 다른 작업을 시작하려고 할 때 강제 종료 문제에 직면하고 있습니다. 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 [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

토스트 메시지가 문제라고 생각합니다. Asynctask에서 Toast 메시지를 제거하고 happns를 봅니다. –

+0

@ChiragRaval 코드에 다른 문제가 있습니까? –

답변

0

에 의해 발생 : java.lang.RuntimeException가 :() 09-18 10시 55분 Looper.prepare라고하지 스레드 내부 핸들러를 만들 수 없습니다 : 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) : 에서 com.widgets.application.MainActivity $ sendMessageAsync. doInBackground (MainActivity.java:260)

당신은 doInBackground() 내부 토스트을 요구하고있다. doInBackground()는 비 -ui 스레드에서 실행되며 UI 함수를 사용할 수 없습니다.

doInBackGround() 안에 아무 것도 토스트하는 대신 플래그를 설정하고 onPostExecute()에 도달하면 해당 플래그의 값을 확인하고 필요한 경우 토스트를 만드십시오.

+0

강제 종료 이유는 무엇입니까? –

+0

'Toast' 문. – Swayam

+0

Toast 문에서 오류가 발생 했습니까? 로그에서 볼 수 있듯이 동시 현재 오류는 어떨까요? –

0

onPostExcute 메소드를 asyncTask에 구현해야합니다. 이 메소드는 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

코드에서 활동을 시작하는 작업을 취소 달성하기 위해 리팩토링 할 필요가있다. 당신이 중단 비동기 작업을 취소 할 때 , 당신이 호출 할 수 있습니다 : 당신의 doInBackground 메소드 내부

yourtask.cancel(true); 

을, 당신이 그것을 취소하지 를 호출되어 있는지 확인해야합니다 가능한 한 빨리 중지을()의 isCancelled . 작업 취소 후 비동기 작업에서 onPostExecute 메서드를 호출하지 않습니다.

시간 제한을 지정하려면 해당 값을 doInBackground 메서드 안에 넣으면 안됩니다. 비동기 메서드를 호출 한 다음 이전 호출을 취소하려면 timeout을 사용하여 두 번째 메서드를 호출하려고합니다.

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

비동기 작업에 간단한 생성자를 추가하여 다른 서버 이름에 대한 다른 작업 클래스를 만들 수 있습니다.