AsyncTask.get()没有进度条

时间:2013-07-18 12:54:01

标签: android web-services android-asynctask

我的应用将数据发送到服务器。它通常工作正常,直到用户处于不良信号区域。如果用户处于良好的信号区域,则以下代码正常工作并发送数据。

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()时显示进度条?

提前谢谢。亚光。

还有任何想法为什么当用户处于不良信号区域时黑屏出现,因此服务器没有响应。这个应用程序似乎导致应用程序很多问题,其后的行为是不寻常的,如在以后发送额外的交易。

[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;
    }

}

1 个答案:

答案 0 :(得分:0)

你根本不需要一个计时器来做你正在尝试的事情(出于某种原因,我认为你试图根据你上面的评论来循环AsyncTask,导致我的。)。如果我理解正确,那么问题在于服务的丢失。你有一个AsyncTask,你可以根据某些条件完成或不完成。你的方法是在一个固定的时间之后使用get和cancle任务,如果它在那之前没有完成执行 - 假设任务没有在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;
}

// ...

} 

此示例使用进度对话框,允许用户通过按下按钮来完成任务。你不打算这样做,而是你要检查网络连接,并根据你的任务是否连接到互联网来设置运行布尔值。如果连接丢失 - 运行将下注设置为false,这将使while循环跳闸并停止任务。

任务完成后的工作。你永远不应该使用get。要么(1)将doInBackgroundCompletes之后需要完成的所有内容放在onPostExecute中(假设它不是太多),要么(2)如果需要将数据返回到起始活动,请使用接口。您可以通过将任务添加为任务构造函数的参数或使用设置接口的单独方法来添加接口。例如

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

将OnTaskComplete侦听器声明为AsyncTask中的实例变量。请注意,我所描述的方法需要使用单独的AsyncTask类。你现在是私人的,这意味着你需要稍微改变你的项目。

<强>更新

要检查连接性,我会使用类似的东西。

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可用,任务将继续。如果不是它会停止。

调用AsyncTask内置的cancle方法是不够的,因为它只能阻止onPostExecute运行。它实际上并没有阻止代码执行。