【问题标题】:ProgressDialog late showing, activity lag using AsyncTaskProgressDialog 延迟显示,活动滞后使用 AsyncTask
【发布时间】:2014-02-27 20:21:59
【问题描述】:

我有 rpc 2.0 服务器,我向其发出请求并获得响应。在 onPreExecute 方法中我定义 ProgressDialog 并调用 show 方法,在 onPostExecute 方法中我调用dismiss ProgressBar,但是当我在进程的最后一秒发出请求和显示progressDialog 时我的活动滞后,有人可以帮我解决这个问题吗?

请求类:

public class HomeCommRequest {

    public static final int ID_GET_MOBILE_AUTH_TOKEN = 1;
    public static final int ID_PIN_LOGIN = 2;   
    public static final int ID_GET_ALL_DEVICES_LIST = 3;    
    public static final int ID_GET_DEVICES_LIST = 4;
    public static final int ID_GET_CU_INFO = 5;
    public static final int ID_GET_DEVICE_INFO = 6;
    public static final int ID_GET_USER_INFO = 7;
    public static final int ID_CHANGE_DEVICE_ALARM_STATE = 8;
    public static final int ID_CHANGE_CU_ALARM_STATE = 9;
    public static final String METHOD_GET_USER_INFO = "getUserInfo";
    public static final String METHOD_GET_CU_INFO = "getCentralUnitInfo";
    public static final String METHOD_GET_ALL_DEVICES_LIST = "getAllDevicesList";   
    public static final String METHOD_GET_MOBILE_AUTH_TOKEN = "getMobileAuthToken";
    public static final String METHOD_PIN_LOGIN = "pinLogin";
    public static final String METHOD_GET_DEVICES_LIST = "getDevicesList";
    public static final String METHOD_CHANGE_DEVICE_ALARM_STATE = "changeAlarmState";
    public static final String METHOD_CHANGE_CU_ALARM_STATE = "changeCUAlarmState";
    public static final String METHOD_GET_DEVICE_INFO = "getDeviceInfo";

    private Map<String,Object> params;
    private Context context;
    private int id;
    private String cookie;
    private String method;
    private ProgressDialog dialog;
    private String serverURL = "MY SERVER URL"

    public HomeCommRequest(int id, String method, Map<String,Object> params, String cookie, Context context)
    {
        this.id = id;
        this.method = method;
        this.params = params;
        this.cookie = cookie;
        this.context = context;
    }

    public <T> T send()
    {
        T resp = null;
        doRequest request = new doRequest();
        request.execute();
        try {
            resp = (T) request.get();

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return resp;
    }



    private String inputStreamToString(InputStream is) {
        String s = "";
        String line = "";       
        // Wrap a BufferedReader around the InputStream
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));      
        // Read response until the end
        try {
            while ((line = rd.readLine()) != null) { s += line; }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
        // Return full string
        return s;
    }
    private JSONObject sendRequest(String method, Map<String,Object> params, int id, String cookieToRequest) throws Exception
    {
        String result = null;
        //Packing inputed parameters into second massive for rpc request
        List paramsToSend = new ArrayList();
        paramsToSend.add(params);
        // Creating a new JSON-RPC 2.0 request
        JSONRPC2Request reqOut = new JSONRPC2Request(method, paramsToSend, id);     
        HttpClient client = new DefaultHttpClient();
        //Creating new HttpPost entry for POST request
        HttpPost post = new HttpPost(serverURL);
        if(cookieToRequest != null)
          post.setHeader("Cookie", "sid=" + cookieToRequest);       

        HttpResponse response = null;
        try {
            //Push JSON string in request
            post.setEntity(new StringEntity(reqOut.toJSONString()));
            //Get response from server
            response = client.execute(post);
        } catch (UnsupportedEncodingException e) {          
            e.printStackTrace();        
        }
        catch(Exception e)
        {
            e.printStackTrace();            
        }
        //Get string from respond entry
        HttpEntity entity = response.getEntity();
        InputStream instream = null;
        if (entity != null) {           
            try {
                instream = entity.getContent();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();    
            }
        //Convert respond to string
            result = inputStreamToString(instream);
        Log.i("HomeCommRequest", "Message from server = " + result);    
        }
        return new JSONObject(result);  
    }

    public class doRequest extends AsyncTask<Void, Void, Response>
    {
        @Override
        protected void onPreExecute() {         
            super.onPreExecute();

        dialog = new ProgressDialog(context, ProgressDialog.THEME_HOLO_LIGHT);
            dialog.setMessage("Please, wait...");
            dialog.setIndeterminate(true);
            dialog.setCancelable(false);
            dialog.show();
        }

        @Override
        protected Response doInBackground(Void... backgroundParams) {

            Response response = null;
            try {
                JSONObject jsonResponseObj = sendRequest(method, params, id, cookie);               

                switch(id)
                {

case ID_PIN_LOGIN: response = new PinLoginResponse(jsonResponseObj);                            

default: Log.e("Request", "Error. doBackground. Invalid id value in switch = " + id);
                }
                publishProgress();

            } catch (Exception e) {             
                e.printStackTrace();
            }
            return response;
        }

        @Override
        protected void onPostExecute(Response result) {
            if(dialog.isShowing())
                dialog.dismiss();

            if(result.hasError())
            {
              AlertDialog.Builder ad = new AlertDialog.Builder(context, AlertDialog.THEME_HOLO_LIGHT);
                ad.setTitle("Error!");
                ad.setMessage(result.getErrorString());
                ad.setPositiveButton("Dismiss", new DialogInterface.OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {}               
                });
                AlertDialog add = ad.create();
                add.show(); 
            }
            super.onPostExecute(result);            
        }

    }

}

响应类示例:

public class PinLoginResponse extends Response {

    private String sessionKey;
    private JSONObject jsonObj;
    private final String TAG = "PinLoginResponse";
    public PinLoginResponse(JSONObject jsonObj){
        this.jsonObj = jsonObj;
        parse(jsonObj);
    }

    public String getSessionKey() {
        return sessionKey;
    }

    public String getErrorStr()
    {
        return errorStr;
    }

    @Override
    public void parse(JSONObject jsonObject)
    {
        errorStr = "No errors";
        try {
            errorStr = jsonObject.get("errors").toString();
            isError = true;
            Log.e(TAG, errorStr + " | " + isError);
        } catch (JSONException e) {
            isError = false;
            //e.printStackTrace();
        }

        try {
            sessionKey = jsonObject.get("result").toString();
        } catch (JSONException e) {
            Log.e(TAG, "No results found");
            e.printStackTrace();
        }       

    }




}

以及我如何在我的活动中使用它:

void getSessionKey(String pincode)
    {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("token", token);
        params.put("pin", pincode);
        HomeCommRequest pinauthRequest = new     HomeCommRequest(HomeCommRequest.ID_PIN_LOGIN,
                                                             HomeCommRequest.METHOD_PIN_LOGIN,
                                                             params,
                                                             null,
                                                             EnterPincodeActivity.this);
        PinLoginResponse getSessionKeyRequest = pinauthRequest.send();
        if(!getSessionKeyRequest.hasError())
        {
            finish();
            Intent tabHostActivityIntent = new Intent(EnterPincodeActivity.this, TabsViewActivity.class);
            tabHostActivityIntent.putExtra("cookie", getSessionKeyRequest.getSessionKey());
            startActivity(tabHostActivityIntent);
        }

【问题讨论】:

    标签: java android android-activity android-asynctask


    【解决方案1】:
    resp = (T) request.get(); 
    

    正在阻塞 UI 线程。 您应该处理onPostExecute() 中的任何响应,而不是强制主线程等待doInBackground() 完成。

    【讨论】:

    • 当您调用 .get() 时,主线程 (UI) 会冻结,因此在 doInBackground() 完成之前不会进行图形计算。试试看,你会看到的。不能保证 onPreExecute() 在 .get() 之前被调用,即使它被调用 ProgressBar 也不会更新。
    • 那么,如何实现服务器请求的进程进度呢? Runnuble 接口适合这种情况吗?
    • AsyncTask 就好了,你需要通知你的 Activity 从 onPostExecute 收到来自服务器的响应。例如,将您的活动作为参数“pinauthRequest.send(yourActivity);”传递并将 AsyncTask 作为参数。
    • 感谢您的回复!祝你有美好的一天
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 2018-05-17
    • 1970-01-01
    • 2014-07-25
    • 2012-08-13
    • 1970-01-01
    相关资源
    最近更新 更多