Web Services Android async rest web request design

yptwkmov  于 2023-03-23  发布在  Android
关注(0)|答案(3)|浏览(134)

我是Android开发新手,当一个人发出asnyc rest web请求时,有以下设计问题。在我的主要活动中,我有一个按钮,使用异步任务执行请求:

public class MainActivity extends ActionBarActivity {

final Context context=this;
.......

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }
    Button btn = (Button)findViewById(R.id.myshowbutton);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            WebRequest wr=new WebRequest(view.getRootView());
            wr.execute("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1");
        }
    });
}

异步任务类在一个单独的java文件中:

public class WebRequest extends AsyncTask<String, String, String> {

private View view;
public WebRequest(View v) {
   this.view = v;
}
@Override
protected String doInBackground(String... uri) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response;
    String responseString = null;
    try {
        response = httpclient.execute(new HttpGet(uri[0]));
        StatusLine statusLine = response.getStatusLine();
        if(statusLine.getStatusCode() == HttpStatus.SC_OK){
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            out.close();
            responseString = out.toString();
        } else{
            //Closes the connection.
            response.getEntity().getContent().close();
            throw new IOException(statusLine.getReasonPhrase());
        }
    } catch (ClientProtocolException e) {
        //TODO Handle problems..
    } catch (IOException e) {
        //TODO Handle problems..
    }
    return responseString;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    EditText et=(EditText)view.findViewById(R.id.editText);
    et.setText(result);
  }
}

正如你所看到的,我将EditText框设置为返回的JSON。我将根视图的引用传递给WebRequest类,以便我可以获得EditText框。
有没有更好的方法来做到这一点?它看起来不是很优雅。也许是一个很好的web请求库?

bt1cpqcv

bt1cpqcv1#

这种方式很好用,知道如何写它是很好的。你可以做一些事情来改进它,还有一个库可以用来大大简化你的代码。

选项1:改进您的代码

首先,您可以使用CallbackActivity中设置EditText中的文本,而不是:
WebRequest中更改这些行:

private View view;
public WebRequest(View v) {
   this.view = v;
}

public interface Callback {
    public void call(String result);
}
private Callback callback;
public WebRequest(Callback c) {
    this.callback = callback;
}

然后在onPostExecute中,只需调用:

callback.call(result);

现在,当您启动Web服务时,您的调用将如下所示:

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        WebRequest wr=new WebRequest(new Callback() {
            @Override
            public void call(String result) {
                ((EditText)view.findViewById(R.id.editText)).setText(result);
            }
        });
        wr.execute("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1");
    }
});

选项2:使用图书馆

但是,如果你确实想使用一个,我推荐我的droidQuery库。使用这个库,你可以从下面简化你的代码:

Button btn = (Button)findViewById(R.id.myshowbutton);
btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        WebRequest wr=new WebRequest(view.getRootView());
        wr.execute("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1");
    }
});

致:

$.with(this, R.id.myshowbutton).click(new Function() {
    @Override
    public void invoke($ d, Object... args) {
        $.ajax(new AjaxOptions().url("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1").success(new Function() {
            @Override
            public void invoke($ d, Object... args) {
                $.with(MyActivity.this, R.id.editText).text(args[0].toString());
            }
        }));
    }
});

您不再需要WebRequest类。

9rygscc1

9rygscc12#

将视图的引用提交到AsyncTask的主要问题是当Activity被销毁并重新创建时会发生什么,例如在方向改变(转动设备)的情况下。在这种情况下,您可能会泄漏对Activity的引用,这可能会导致昂贵的内存。
有几个库试图帮助解决这类问题。也许还可以看看RoboSpice

vulvrdjw

vulvrdjw3#

如果您想将EditTextWebRequest中解耦,请考虑为MainActivity创建一个回调接口来实现。
MainActivity.java

public class MainActivity extends ActionBarActivity implements WebRequestCallback {
    ...
    @Override
    public void handleStringResult(String result) {
        btn.setText(result);
    }
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                WebRequest wr = new WebRequest(this);
                wr.execute("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1");
            }
        });
    }
    ...
}

WebRequestCallback.java

public interface WebRequestCallback {
    public void handleStringResult(String result);
}

WebRequest.java

public class WebRequest extends AsyncTask<String, String, String> {

    private WebRequestCallback callback;

    public WebRequest(WebRequestCallback callback) {
       this.callback = callback;
    }

    @Override
    protected String doInBackground(String... uri) {
        ...
    }

    @Override
    protected void onPostExecute(String result) {
        callback.handleStringResult(result);
    }
}

此外,虽然我自己没有使用过它,但如果你正在寻找一个更强大的Android网络库,我听说过关于**Ion**的好消息。

相关问题