AsyncTask.get()没有进度条 [英] AsyncTask.get() no progress bar

查看:232
本文介绍了AsyncTask.get()没有进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序发送数据到服务器。它一般,直到用户是一个不好的信号区域工作正常。如果用户是在一个良好的信号区域的下面code正常工作和数据发送

 的String [] = PARAMS新的String [] {compID,TAGID,tagClientId,carerID,
                formattedTagScanTime,formattedNowTime,statusForWbService,getDeviceName(),tagLatitude,tagLongitude};
        AsyncPostData APD =新AsyncPostData();            apd.execute(PARAMS);

 私有类AsyncPostData扩展的AsyncTask<弦乐,太虚,字符串> {        ProgressDialog progressDialog;
        串dateTimeScanned;        @覆盖
        在preExecute保护无效()
        {
           // progressDialog = ProgressDialog.show(NfcscannerActivity.this,
                //连接到服务器,发布的数据......,真);            INT buildVersionSdk = Build.VERSION.SDK_INT;
            INT buildVersion codeS = Build.VERSION_ codeS.GINGERBREAD;            Log.e(TAGbuildVersionSdk =+ buildVersionSdk
                    +buildVersion codeS =+ buildVersion codeS);            INT themeVersion;
            如果(Build.VERSION.SDK_INT> Build.VERSION_ codeS.GINGERBREAD){                 themeVersion = 2;            }其他{                 themeVersion = 1;
            }            progressDialog =新ProgressDialog(NfcscannerActivity.this,themeVersion);
            progressDialog.setTitle(连接到服务器);
            progressDialog.setMessage(发送数据到服务器...);
            progressDialog.setIndeterminate(真);            尝试{
            progressDialog.show();
            }赶上(例外五){                //忽视
            }
        };
        @覆盖
        保护字符串doInBackground(字符串... PARAMS){            Log.e(TAGcarerid在doinbackground =+参数[3] +dateTimeScanned在AsyncPost为duplecate TX =+参数[4]);            dateTimeScanned =参数[4];            返回nfcscannerapplication.loginWebservice.postData(PARAMS [0],则params [1],则params [2],则params [3],则params [4],
                    PARAMS [5],则params [6],则params [7] + getVersionName(),则params [8],则params [9]);        }         @覆盖
            保护无效onPostExecute(字符串结果)
            {
             super.onPostExecute(结果);                尝试{
                progressDialog.dismiss();
                }赶上(例外五){
                    //忽视
                }                如果(结果=空&放大器;!&放大器; result.trim()equalsIgnoreCase(OK)){                    Log.e(TAG,关于与servertime更新DB);
                    日期时间sentToServerAt =新的DateTime();
                    nfcscannerapplication.loginValidate.updateTransactionWithServerTime(sentToServerAt,NULL);
                    nfcscannerapplication.loginValidate.insertIntoDuplicateTransactions(dateTimeScanned);                    TAGID = NULL;
                    tagType = NULL;
                    tagClientId = NULL;                    //调用来刷新未发送的交易的TextView
                    onResume();                }否则如果(结果=空&放大器;&安培; result.trim()equalsIgnoreCase(错误:TX复制!)){
                    Log.e(TAG,从服务器的响应是重复交易);
                    // NB。以下的时间可能不与服务器上的时间完全一致
                    //因为这个TX已被处理,但确定从来没有达到过的手机,
                    //所以我们只是要更新手机的时间DupTX DB所以手机不保留
                    //发送。                    日期时间sentToServerTimeWhenDupTX =新的DateTime();
                    nfcscannerapplication.loginValidate.updateTransactionWithServerTime(sentToServerTimeWhenDupTX,NULL);                    TAGID = NULL;
                    tagType = NULL;
                    tagClientId = NULL;                }其他{                    Toast.makeText(NfcscannerActivity.this,
                            没有手机信号或服务器问题,
                            Toast.LENGTH_LONG).show();
                }
            }    } // AsyncPostData结束

在信号不好的地区应用往往呈现出黑色的屏幕一会儿渲染应用程序无法使用之前展现了几分钟进度条。

我想解决的办法是要做到以下几点。

 的String [] = PARAMS新的String [] {compID,TAGID,tagClientId,carerID,
                formattedTagScanTime,formattedNowTime,statusForWbService,getDeviceName(),tagLatitude,tagLongitude};
        AsyncPostData APD =新AsyncPostData();
        尝试{
            apd.execute(PARAMS)获得(10,TimeUnit.SECONDS);
        }赶上(InterruptedException的E){
            // TODO自动生成catch块
            e.printStackTrace();
        }赶上(为ExecutionException E){
            // TODO自动生成catch块
            e.printStackTrace();
        }赶上(TimeoutException异常五){
            // TODO自动生成catch块
            e.printStackTrace();
        }

这将导致的AsyncTask到10秒后取消,但是因为它是在执行存在黑屏直到数据发送后跟进度几的毫秒。

有没有一种方法来显示进度,同时执行一个AsyncTask.get()?

在此先感谢。马特。

另外还有什么想法,为什么黑屏正值当用户在信号不好的地区,为此服务器没有响应。此塞纳里奥似乎会导致问题的应用很多,其中它的行为是不寻常的后像在稍后的日期发送额外的事务。

 公共类SignalService延伸服务{    NfcScannerApplication nfcScannerApplication;
    TelephonyManager SignalManager;
    PhoneStateListener signalListener;
    私有静态最终诠释LISTEN_NONE = 0;
    私有静态最后弦乐TAG = SignalService.class.getSimpleName();
    @覆盖
    公共无效的onCreate(){
        super.onCreate();
        // TODO自动生成方法存根
        Log.e(TAGSignalService创建);
        nfcScannerApplication =(NfcScannerApplication)getApplication();
        signalListener =新PhoneStateListener(){
            公共无效onSignalStrengthChanged(INT ASU){
                //Log.e(\"onSignalStrengthChanged:,信号强度=+ ASU);
                nfcScannerApplication.setSignalStrength(ASU);            }
        };    }    @覆盖
    公共无效的onDestroy(){
        super.onDestroy();
        // TODO自动生成方法存根
        Log.e(TAGSignalService摧毁);
        SignalManager.listen(signalListener,LISTEN_NONE);    }    @覆盖
    公共无效调用onStart(意向意图,诠释startId){
        super.onStart(意向,startId);
        // TODO自动生成方法存根
        Log.e(TAG,SignalService处理通信);         SignalManager =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
         SignalManager.listen(signalListener,PhoneStateListener.LISTEN_SIGNAL_STRENGTH);    }    @覆盖
    公众的IBinder onBind(意向意图){
        // TODO自动生成方法存根
        返回null;
    }}


解决方案

您不需要一个计时器都做你尝试什么(由于某种原因,我还以为你想循环 AsyncTask的根据您的上述评论导致我的。)。如果我理解正确你的问题是服务的损失。你有一个的AsyncTask 你开始可能会或可能不会根据某些条件完成。你的方法是使用获取和事件的固定时间,它没有执行完之前再经过CANCLE任务 - 的假设是,如果任务没有完成在10秒切断,服务丢了。

有一个更好的办法来解决这个问题是使用indcates网络连接是否可用一个布尔标志,然后从服务是否丢失停止执行任务。下面是我从这个帖子为例(我的道歉格式化我是一个蹩脚的电脑上 - 所有的东西 - IE8 - 所以我不能看到code的样子)。

 公共类MyTask扩展的AsyncTask<太虚,太虚,太虚> {私人挥发性布尔运行= TRUE;
私人最终ProgressDialog progressDialog;公共MyTask(上下文CTX){
    progressDialog = gimmeOne(CTX);    progressDialog.setCancelable(真);
    progressDialog.setOnCancelListener(新OnCancelListener(){
        @覆盖
        公共无效onCancel(DialogInterface对话){
            //实际上可以设置运行= FALSE;就在这里,但我会
            //坚持收缩。
            取消(真);
        }
    });}@覆盖
在preExecute保护无效(){
    progressDialog.show();
}@覆盖
保护无效onCancelled(){
    运行= FALSE;
}@覆盖
保护无效doInBackground(虚空...... PARAMS){    而(运行){
        //的辛勤工作
    }
    返回null;
}// ...}

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

对于完成任务后的工作。你永远不应该使用get。无论是(1)将需要在以后的onPostExecute doInBackgroundCompletes(假设它不是太多)或(2)如果你需要获取数据回到起始活动使用的界面做的一切。您可以通过添加作为参数传递给您的任务构造函数或使用该设置界面了一个单独的方法添加的接口。例如:

 公共无效setInterface(OnTaskComplete监听){
    this.listener =侦听器;
}

在哪里OnTaskComplete监听器被声明为在的AsyncTask 实例变量。请注意我描述的方法需要使用一个单独的的AsyncTask 类。你的现在,这意味着你需要改变你的项目一点是私人的。

更新

要检查连接我会用这样的事情。

 公共布尔isNetworkOnline(){
布尔状态= FALSE;
尝试{
    ConnectivityManager厘米=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    的NetworkInfo的NetInfo = cm.getNetworkInfo(0);
    如果(NetInfo的= NULL&放大器;!&安培; netInfo.getState()== NetworkInfo.State.CONNECTED){
        状态= TRUE;
    }其他{
        的NetInfo = cm.getNetworkInfo(1);
        如果(NetInfo的= NULL&放大器;!&安培; netInfo.getState()== NetworkInfo.State.CONNECTED)
            状态= TRUE;
    }
}赶上(例外五){
    e.printStackTrace();
    返回false;
}
返回状态;}

您可以检查,看看是否有在您的应用可以连接到服务器疗法的实际的网络连接。这种方法并不一定是公共的,可以是你的AsyncTask 类的一部分。就个人而言,我使用的网络管理器类,我用它来检查各种网络统计数据(其中一个是我可以连接到互联网)与此类似。

您会检查连接你开始在你的doInBackground方法执行循环前,那么你可以在整个该方法的过程中公司定期更新。如果netowkr可用的任务将继续。如果不是,将停止。

调用内置的CANCLE方法的AsyncTask 是不够的,原因是其唯一prevent onPostExecute运行。它实际上并没有从execting停止code。

My app sends data to the server. It generally works fine until the user is in a bad signal area. If the user is in a good signal area the the following code works fine and the data is sent.

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 

.

The app in bad signal areas tends to show the progress bar for a few minutes before showing a black screen for a while rendering the app unusable.

I thought a way around this would be to do the following.

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();
        }

This will cause the AsyncTask to cancel after 10 seconds, but as it is executing there is a black screen until the data is sent followed by the progressbar for a few millisecs.

Is there a way to show the progressbar whilst executing an AsyncTask.get()?

thanks in advance. matt.

Also are there any ideas why the black screen comes when the user is in bad signal area and therefor no response from the server. This senario seems to cause the app alot of problems where it's behavior is unusual afterwards like sending extra transactions at a later date.

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

}

解决方案

You do not need a timer at all to do what you're attempting (for some reason I thought you were trying to loop the AsyncTask based on your comments above which resulted in mine.). If I understand correctly you're issue is with the loss of service. You have an AsyncTask that you start which may or may not finish depending on certain conditions. Your approach was to use get and cancle the task after a fixed time in the event that it did not finish executing before then - the assumption being if the task didn't finish within the 10 second cut off, service was lost.

A better way to approach this problem is to use a boolean flag that indcates whether network connectivity is available and then stop the task from executing if service is lost. Here is an example I took from this post (I apologize for the formatting I'm on a crappy computer with - of all things - IE8 - so I can't see what the code looks like).

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

// ...

} 

This example uses a progress dialog that allows the user to cancle the task by pressing a button. You're not going to do that but rather you're going to check for network connectivty and set the running boolean based on whether your task is connected to the internet. If connection is lost - running will bet set to false which will trip the while loop and stop the task.

As for the work after the task complete. You should NEVER use get. Either (1) put everything that needs to be done after the doInBackgroundCompletes in onPostExecute (assuming its not too much) or (2) if you need to get the data back to the starting activity use an interface. You can add an interface by either adding as an argument to your tasks constructor or using a seperate method that sets the interface up. For example

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

Where OnTaskComplete listener is declared as an instance variable in your AsyncTask. Note the approach I am describing requires using a seperate AsyncTask class. Your's is private right now which means you need to change your project a little.

UPDATE

To check connectivity I would use something like this.

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;

}  

You can check to see if there is an actual network connection over which your app can connect to ther server. This method doesn't have to be public and can be part of you're AsyncTask class. Personally, I use something similar to this in a network manager class that I use to check various network statistics (one of which is can I connect to the internet).

You would check connectivity before you started executing the loop in your doInBackground method and then you could periodicly update throughout the course of that method. If netowkr is available the task will continue. If not it will stop.

Calling the AsyncTask built in cancle method is not sufficient becuase it only prevent onPostExecute from running. It does not actually stop the code from execting.

这篇关于AsyncTask.get()没有进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆