如何制作一个阻塞的 Android HttpRequest

发布于 2024-12-29 23:22:39 字数 3346 浏览 2 评论 0原文

这是我的问题: 我有一个从服务器检索的值列表。 这些值填充 UI 中的 ListView。 在列表填满之前,我无法继续加载视图并将其显示给用户。 由于 Android 强制我在单独的线程中进行 http 调用,我的问题是如何创建 1 个执行 httprequests 的类,并且在调用类中我等待直到收到 HttpRequest 的响应,然后才继续加载视图? 现在我有这个类来执行请求:

public class WapConnector extends AsyncTask<String, String, String>{
private static final String TAG = "WapConnector";
private String html = "";
private Handler mHandler;
private String server = "http://....whatever";
private String callUrl = "/api/";
private String params = "login?u=Admin&pw=234234&format=json";
private int _callstate = 1;


@Override
protected String doInBackground(String... uri) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response;
    String responseString = null;
    try {
        String fullUrl = "";
        Log.i(TAG,fullUrl);
        if(params.length() > 0){
            fullUrl = server + callUrl + params + "&alf_ticket=" + Globals.getInstance().getTicket() + "&udid=" + Globals.getInstance().udid() + "&phoneNumber=" + Globals.getInstance().phoneNumber();
        }
        else{
            fullUrl = server + callUrl + "?udid=" + Globals.getInstance().udid() + "&alf_ticket=" + Globals.getInstance().getTicket() + "&phoneNumber=" + Globals.getInstance().phoneNumber();
        }
        Log.i(TAG,fullUrl);
        response = httpclient.execute(new HttpGet(fullUrl));
        StatusLine statusLine = response.getStatusLine();
        if(statusLine.getStatusCode() == HttpStatus.SC_OK){
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            out.close();
            responseString = out.toString();
            Log.i(TAG,responseString);
        } else{
            //Closes the connection.
            response.getEntity().getContent().close();
            throw new IOException(statusLine.getReasonPhrase());
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
        //TODO Handle problems..
    } catch (IOException e) {
        //TODO Handle problems..
        e.printStackTrace();
    }
    return responseString;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    Log.i(TAG + "onPostExecute",result);
    activity.getClass().handleResponse();
        //main load
        JSONObject jobj;
        JSONObject jvalue;
        try {
            jobj = new JSONObject(result);
            if(_callstate == 1){
                jvalue = jobj.getJSONObject("data");
                String ticket = jvalue.getString("ticket");
                Log.i("loginwap",ticket);
                Globals.getInstance().setTicket(ticket);
                _callstate = 2;
            }
            else{
                jvalue = jobj.getJSONObject("countries");
                JSONArray countries = jvalue.getJSONArray("countries");

            }
        }
        catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

这就是我从父类进行调用的方式:

WapConnector wap = new WapConnector();
    wap.setCallUrl("/anyurl/");
    wap.callstate(3);
    wap.setParams("");
    wap.execute("");

现在我的问题是,由于请求在线程中运行,一旦我调用 wap.execute(),我的 Activity 就会继续加载,但是我希望它等到我得到响应,解析响应,然后才继续加载。

谢谢大家的回复。!​​!!

Here is my issue:
I have a list of values which I retrieve from server.
These values fill ListView in the UI.
I cannot continue loading the View and showing it to user until the list is full.
Since Android forces me to make http calls in separate thread, my question is how do I create 1 class that does the httprequests and in the calling class I wait until I get response from the HttpRequest and only then I proceed loading the View?
Right now I have this class that does the requests:

public class WapConnector extends AsyncTask<String, String, String>{
private static final String TAG = "WapConnector";
private String html = "";
private Handler mHandler;
private String server = "http://....whatever";
private String callUrl = "/api/";
private String params = "login?u=Admin&pw=234234&format=json";
private int _callstate = 1;


@Override
protected String doInBackground(String... uri) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response;
    String responseString = null;
    try {
        String fullUrl = "";
        Log.i(TAG,fullUrl);
        if(params.length() > 0){
            fullUrl = server + callUrl + params + "&alf_ticket=" + Globals.getInstance().getTicket() + "&udid=" + Globals.getInstance().udid() + "&phoneNumber=" + Globals.getInstance().phoneNumber();
        }
        else{
            fullUrl = server + callUrl + "?udid=" + Globals.getInstance().udid() + "&alf_ticket=" + Globals.getInstance().getTicket() + "&phoneNumber=" + Globals.getInstance().phoneNumber();
        }
        Log.i(TAG,fullUrl);
        response = httpclient.execute(new HttpGet(fullUrl));
        StatusLine statusLine = response.getStatusLine();
        if(statusLine.getStatusCode() == HttpStatus.SC_OK){
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            out.close();
            responseString = out.toString();
            Log.i(TAG,responseString);
        } else{
            //Closes the connection.
            response.getEntity().getContent().close();
            throw new IOException(statusLine.getReasonPhrase());
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
        //TODO Handle problems..
    } catch (IOException e) {
        //TODO Handle problems..
        e.printStackTrace();
    }
    return responseString;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    Log.i(TAG + "onPostExecute",result);
    activity.getClass().handleResponse();
        //main load
        JSONObject jobj;
        JSONObject jvalue;
        try {
            jobj = new JSONObject(result);
            if(_callstate == 1){
                jvalue = jobj.getJSONObject("data");
                String ticket = jvalue.getString("ticket");
                Log.i("loginwap",ticket);
                Globals.getInstance().setTicket(ticket);
                _callstate = 2;
            }
            else{
                jvalue = jobj.getJSONObject("countries");
                JSONArray countries = jvalue.getJSONArray("countries");

            }
        }
        catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

And this is how I make calls from Parent classes:

WapConnector wap = new WapConnector();
    wap.setCallUrl("/anyurl/");
    wap.callstate(3);
    wap.setParams("");
    wap.execute("");

Now my issue is that since the request runs in thread, once I call wap.execute(), my Activity continues to load, but I want it to wait until I get response, parse the response and only then continue to load.

thanks everyone for replies.!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

关于从前 2025-01-05 23:22:39

将上下文从您调用它的活动传递到您的类。重载 onPreExecute() 以显示 ProgressDialog,然后重载 onPostExecute() 以隐藏 ProgressDialog。这会阻止您加载,同时让您正在加载的用户加载。

有一种有点狡猾的方法来获得更多的控制权。如果要将 AsyncTask 保留为单独的类,但允许它更新另一个 Activity 中的 UI 元素,请在该 Activity 中定义一个 Handler,然后将其传递到 AsyncTask 的构造函数中。然后,您可以在 AsyncTask 的 onPostExecute() 方法中向处理程序发送一条消息,告诉它更新 UI。您需要确保处理程序正确处理 AsyncTask 发回的消息。可能会更干净一些,但它可以工作,并且允许您重用跨活动进行网络调用的 asyncTask。

Pass in a context to your class from the activity you are calling it from. Overload the onPreExecute() to show a ProgressDialog and then overload onPostExecute() to hide the ProgressDialog. This gives you blocking while letting the user you are loading.

There is a kinda hacky way to get more control. If you want to keep the AsyncTask as a separate class but allow it to update UI elements in another Activity, define a Handler in that Activity and then pass it in the constructor of the the AsyncTask. You can then send a message in the onPostExecute() method of your AsyncTask to the handler to tell it to update the UI. You will need to make sure the handler is properly handling the message your AsyncTask is sending back. Could be a little cleaner, but it works and will allow you to reuse an asyncTask that makes a network call across activities.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文