2013-07-18 2 views
0

내 앱이 서버로 데이터를 보냅니다. 그것은 일반적으로 사용자가 나쁜 신호 영역에있을 때까지 잘 작동합니다. 사용자가 좋은 신호 영역에 있으면 다음 코드가 제대로 작동하고 데이터가 전송됩니다.AsyncTask.get() 진행률 표시 줄이 없음

String[] params = new String[]{compID, tagId, tagClientId, carerID, 
       formattedTagScanTime, formattedNowTime, statusForWbService, getDeviceName(), tagLatitude, tagLongitude}; 
     AsyncPostData apd = new AsyncPostData(); 

      apd.execute(params); 

.

private class AsyncPostData extends AsyncTask<String, Void, String> { 

     ProgressDialog progressDialog; 
     String dateTimeScanned; 

     @Override 
     protected void onPreExecute() 
     { 


      // progressDialog= ProgressDialog.show(NfcscannerActivity.this, 
       // "Connecting to Server"," Posting data...", true); 

      int buildVersionSdk = Build.VERSION.SDK_INT; 
      int buildVersionCodes = Build.VERSION_CODES.GINGERBREAD; 

      Log.e(TAG, "buildVersionSdk = " + buildVersionSdk 
        + "buildVersionCodes = " + buildVersionCodes); 

      int themeVersion; 
      if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) { 

       themeVersion = 2; 

      }else{ 

       themeVersion = 1; 
      } 

      progressDialog = new ProgressDialog(NfcscannerActivity.this, themeVersion); 
      progressDialog.setTitle("Connecting to Server"); 
      progressDialog.setMessage(" Sending data to server..."); 
      progressDialog.setIndeterminate(true); 

      try{ 
      progressDialog.show(); 
      }catch(Exception e){ 

       //ignore 
      } 
     }; 


     @Override 
     protected String doInBackground(String... params) { 

      Log.e(TAG, "carerid in doinbackground = " + params[3] + " dateTimeScanned in AsyncPost for the duplecate TX = " + params[4]); 

      dateTimeScanned = params[4]; 

      return nfcscannerapplication.loginWebservice.postData(params[0], params[1], params[2], params[3], params[4], 
        params[5], params[6], params[7] + getVersionName(), params[8], params[9]); 

     } 

     @Override 
      protected void onPostExecute(String result) 
      { 
      super.onPostExecute(result); 

       try{ 
       progressDialog.dismiss(); 
       }catch(Exception e){ 
        //ignore 
       } 

       if(result != null && result.trim().equalsIgnoreCase("OK") ){ 

        Log.e(TAG, "about to update DB with servertime"); 
        DateTime sentToServerAt = new DateTime(); 
        nfcscannerapplication.loginValidate.updateTransactionWithServerTime(sentToServerAt,null); 
        nfcscannerapplication.loginValidate.insertIntoDuplicateTransactions(dateTimeScanned); 

        tagId = null; 
        tagType = null; 
        tagClientId = null; 

        //called to refresh the unsent transactions textview 
        onResume(); 

       }else if(result != null && result.trim().equalsIgnoreCase("Error: TX duplicated")){ 
        Log.e(TAG, "response from server is Duplicate Transaction "); 


        //NB. the following time may not correspond exactly with the time on the server 
        //because this TX has already been processed but the 'OK' never reached the phone, 
        //so we are just going to update the phone's DB with the DupTX time so the phone doesn't keep 
        //sending it. 

        DateTime sentToServerTimeWhenDupTX = new DateTime(); 
        nfcscannerapplication.loginValidate.updateTransactionWithServerTime(sentToServerTimeWhenDupTX,null); 

        tagId = null; 
        tagType = null; 
        tagClientId = null; 



       }else{ 

        Toast.makeText(NfcscannerActivity.this, 
          "No phone signal or server problem", 
          Toast.LENGTH_LONG).show(); 
       } 
      } 

    }//end of AsyncPostData 

.

불량 신호 영역의 앱은 잠시 동안 검은 색 화면을 표시하기 전에 진행률 막대를 표시하는 경향이있어 잠시 동안 앱을 사용할 수 없게 만듭니다.

나는이 문제를 해결할 방법이 다음과 같을 것이라고 생각했습니다.

String[] params = new String[]{compID, tagId, tagClientId, carerID, 
       formattedTagScanTime, formattedNowTime, statusForWbService, getDeviceName(), tagLatitude, tagLongitude}; 
     AsyncPostData apd = new AsyncPostData(); 
     try { 
      apd.execute(params).get(10, TimeUnit.SECONDS); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (TimeoutException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

은 AsyncTask를 10 초 후에 해제하게하지만 실행으로 데이터가 몇 밀리 세컨드에 대해 진행 막대 뒤에 보낼 때까지 검은 화면있을 것이다.

AsyncTask.get()을 실행하는 동안 진행률 표시 줄을 표시하는 방법이 있습니까? 사전에

감사합니다. 매트.

또한 사용자가 불량 신호 영역에있을 때 검은 색 화면이 나타나서 서버에서 응답이없는 이유가 있습니다. 이 senario는 추후에 추가 트랜잭션을 보내는 것과 같이 문제가 많이 발생하는 것으로 보입니다.

는 [EDIT1]

public class SignalService extends Service{ 

    NfcScannerApplication nfcScannerApplication; 
    TelephonyManager SignalManager; 
    PhoneStateListener signalListener; 
    private static final int LISTEN_NONE = 0; 
    private static final String TAG = SignalService.class.getSimpleName(); 


    @Override 
    public void onCreate() { 
     super.onCreate(); 
     // TODO Auto-generated method stub 
     Log.e(TAG, "SignalService created"); 
     nfcScannerApplication = (NfcScannerApplication) getApplication(); 
     signalListener = new PhoneStateListener() { 
      public void onSignalStrengthChanged(int asu) { 
       //Log.e("onSignalStrengthChanged: " , "Signal strength = "+ asu); 
       nfcScannerApplication.setSignalStrength(asu); 

      } 
     }; 

    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     // TODO Auto-generated method stub 
     Log.e(TAG, "SignalService destroyed"); 
     SignalManager.listen(signalListener, LISTEN_NONE); 

    } 

    @Override 
    public void onStart(Intent intent, int startId) { 
     super.onStart(intent, startId); 
     // TODO Auto-generated method stub 
     Log.e(TAG, "SignalService in onStart"); 

     SignalManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
     SignalManager.listen(signalListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH); 

    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

} 
+0

get()을 사용하면 UX가 악화됩니다 : [AsyncTask가 실행되는 동안 검은 색 화면] (http://stackoverflow.com/a/15259698/2558882). – Vikram

+0

mmm 네, UI 스레드를 차단한다는 것을 알고 있습니다.하지만 .get()을 사용하지 않고 asynctask에 타이머를 설정하여 취소 할 수있는 방법을 모르겠습니다. – turtleboy

+0

핸들러를 사용하여 asynctask를 취소 할 수 있습니까? – turtleboy

답변

0

당신은 당신이 당신의 의견에 따라 루프 AsyncTask하려고하는 줄 알았는데 몇 가지 이유 (시도하고 일을하는 모든 타이머가 필요하지 않습니다는 위의 결과 광산.). 내가 올바르게 이해한다면 문제는 서비스를 잃는 것입니다. 특정 조건에 따라 시작할 수도 있고하지 않을 수도있는 AsyncTask이 있습니다. 당신의 접근 방식은 그때까지 실행이 끝나지 않은 경우 고정 된 시간 후에 작업을 가져오고 취소하는 것입니다. 작업이 10 초 내에 끝나지 않으면 서비스가 손실됩니다.

이 문제에 접근하는 더 좋은 방법은 네트워크 연결을 사용할 수 있는지 여부를 표시하고 서비스가 손실 될 경우 작업 실행을 중지하는 부울 플래그를 사용하는 것입니다. 다음은 내가 this post에서 가져온 예제입니다. (나는 포맷팅을하는 것에 대해 사과합니다. - 모든 것 - IE8 - 그래서 코드가 어떻게 보이는지 알 수 없습니다.)

public class MyTask extends AsyncTask<Void, Void, Void> { 

private volatile boolean running = true; 
private final ProgressDialog progressDialog; 

public MyTask(Context ctx) { 
    progressDialog = gimmeOne(ctx); 

    progressDialog.setCancelable(true); 
    progressDialog.setOnCancelListener(new OnCancelListener() { 
     @Override 
     public void onCancel(DialogInterface dialog) { 
      // actually could set running = false; right here, but I'll 
      // stick to contract. 
      cancel(true); 
     } 
    }); 

} 

@Override 
protected void onPreExecute() { 
    progressDialog.show(); 
} 

@Override 
protected void onCancelled() { 
    running = false; 
} 

@Override 
protected Void doInBackground(Void... params) { 

    while (running) { 
     // does the hard work 
    } 
    return null; 
} 

// ... 

} 

이 예에서는 사용자가 단추를 눌러 작업을 취소 할 수있는 진행 대화 상자를 사용합니다. 당신은 그렇게하지 않을 것이 아니라 네트워크 연결 상태를 점검하고 작업이 인터넷에 연결되어 있는지 여부에 따라 실행중인 부울 값을 설정합니다. 연결이 끊어지면 running이 false로 설정되어 while 루프를 트립하고 작업을 중지합니다.

작업 완료 후 작업. get을 사용해서는 안됩니다. (1) onPostExecute의 doInBackgroundCompletes 이후에 수행해야 할 모든 작업을 수행하십시오 (너무 많지 않다고 가정) 또는 (2) 시작 활동으로 데이터를 가져와야하는 경우 인터페이스를 사용하십시오. 작업 생성자에 인수를 추가하거나 인터페이스를 설정하는 별도의 메서드를 사용하여 인터페이스를 추가 할 수 있습니다.OnTaskComplete 리스너가 당신의 AsyncTask의 인스턴스 변수로 선언 예를

public void setInterface(OnTaskComplete listener){ 
    this.listener = listener; 
} 

하십시오. 내가 설명하고있는 접근 방식은 별도의 AsyncTask 클래스를 사용해야한다는 점에 유의하십시오. 네가 지금은 비공식적인데, 이는 프로젝트를 조금 바꿔야한다는 것을 의미한다.

UPDATE

는 연결을 나는 이런 식으로 뭔가를 사용하는 것이 확인하십시오.

public boolean isNetworkOnline() { 
boolean status=false; 
try{ 
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo netInfo = cm.getNetworkInfo(0); 
    if (netInfo != null && netInfo.getState()==NetworkInfo.State.CONNECTED) { 
     status= true; 
    }else { 
     netInfo = cm.getNetworkInfo(1); 
     if(netInfo!=null && netInfo.getState()==NetworkInfo.State.CONNECTED) 
      status= true; 
    } 
}catch(Exception e){ 
    e.printStackTrace(); 
    return false; 
} 
return status; 

} 

앱이 서버에 연결할 수있는 실제 네트워크 연결이 있는지 확인할 수 있습니다. 이 방법은 공개 일 필요는 없으며 사용자가 AsyncTask 클래스 일 수 있습니다. 개인적으로, 나는 다양한 네트워크 통계 (하나는 인터넷에 연결할 수 있음)를 확인하는 데 사용하는 네트워크 관리자 클래스에서 이와 비슷한 것을 사용합니다.

doInBackground 메서드에서 루프를 실행하기 전에 연결을 확인한 다음 해당 메서드의 과정을 통해 정기적으로 업데이트 할 수 있습니다. netowkr을 사용할 수 있으면 작업이 계속됩니다. 그렇지 않으면 중지됩니다.

cancle 메서드가 내장 된 AsyncTask을 호출하는 것은 onPostExecute가 실행되지 못하도록하기 때문에 충분하지 않습니다. 실제로 코드가 실행되지 않습니다.

+0

안녕하세요, 귀하의 의견을 주셔서 감사합니다. 나는 당신이 의미하는 바를 이해하지만, 네트워크 연결 확인에 관해 더 자세히 설명 할 수 있습니다. 신호 강도를 확인하는 코드를 작성했지만 때때로 신뢰할 수 없다는 것을 발견했습니다 (항상 신호가 없다는 것을 말함). 신호 코드로 수정 사항을 게시했습니다. 올바른 라인을 따라 편집 했습니까? 감사 – turtleboy

관련 문제