android 请求网络api,Android发起网络Request与接收Response

以下几种写法很常见:

1、直接 new Thread 进行请求,数据返回后使用 handler 回到主线程进行 UI 刷新。

1

2

3

4

5

6

7

8

9

10

11

12

13

14private void getData() {        new Thread(new Runnable() {            @Override

public void run() {                final String result = GetDataHelper.getData();

ShowImageActivity.this.runOnUiThread(new Runnable() {                    @Override

public void run() {                        // 处理结果,更新 UI

}

});

}

}).start();

}

2、或 直接 new AsyncTask。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15private void getData() {        new AsyncTask(){

@Override            protected String doInBackground(String... params) {                String retult = GetDataHelper.getData();                return retult;

}

@Override            protected void onPostExecute(String result) {                // 处理结果,更新 UI

}

}.execute("params");

}

3、使用封装好的网络请求库

1

2

3

4

5

6

7

8

9

10

11

12

13JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("api", null,                new Response.Listener() {

@Override                    public void onResponse(JSONObject response) {                        Log.d("TAG", response.toString());

}

}, new Response.ErrorListener() {

@Override            public void onErrorResponse(VolleyError error) {                Log.e("TAG", error.getMessage(), error);

}

});

问题来了,就是面试被问烂了的匿名内部类隐式地持有其外部类的引用,在内部类的生命比外部类的生命要长的情景下会引起内存泄露。

面试者都会说,使用静态内部类可以解决这个问题,在这里就不再多说,具体解决可参考技术小黑屋的:

面试时大家都会说使用静态内部类代替非静态内部类和匿名内部类,但为什么以上几种会引起内存泄露的写法还是这么多人用、在项目中还是那么常见呢?

静态内部类繁琐?

不介意短暂的内存泄露?反正响应返回或超时后都会释放?

以上写法除了内存泄露问题,还存在缺乏线程管理、统一调度,耦合等问题。

还有没更优雅的做法?

API 请求中心化管理,提供静态方法给外部调用,不设置回调函数(回调引用一样会引起内存泄露),使用事件总线(EventBus、otto 或 自己写)进行响应的结果分发,观察者在生命周期注册与反注册事件监听。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38public class APIManager {    private static RequestQueue mQueue;    public void init(Context context){

mQueue  = Volley.newRequestQueue(context);

}    public static void register(String username, String psw){        //do register

}    public static void login(String username, String psw){        //do login

}    public static void getData(){

String getDataUrl = "XXXXX";

JsonObjectRequest request = creatJsonObjectRequest(getDataUrl, null, new Response.Listener() {

@Override            public void onResponse(JSONObject response) {

GetDataEvent event = new GetDataEvent(0, response.toString());

EventBus.getDefault().post(event);

}

}, new Response.ErrorListener() {

@Override            public void onErrorResponse(VolleyError error) {

GetDataEvent event = new GetDataEvent(-1, error.getMessage());

EventBus.getDefault().post(event);

}

});

mQueue.add(request);

}    private static JsonObjectRequest creatJsonObjectRequest(String url, JSONObject requestObject, Response.Listener listener, Response.ErrorListener errorListener){        return new JsonObjectRequest(url, requestObject, listener, errorListener);

}

}

API 请求中心化管理,这里以 Volley 为例。若是自己封装的网络请求,也可以自定义线程池去管理线程。

提供静态方法getData()给外部调用,不需传入回调函数,与外部脱离引用关系,解耦。请求响应后使用事件总线(这里以 EventBus 为例)分发响应结果事件EventBus.getDefault().post(event)

观察者,这里即当前 Activity

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19@Override

protected void onResume() {        super.onResume();        // 注册监听

EventBus.getDefault().register(this);

}    @Override

protected void onStop() {        // 反注册监听

EventBus.getDefault().unregister(this);        super.onStop();

}    @Subscribe

public void onMessageEvent(GetDataEvent event){        int errorCode = event.getErrorCode();

String message = event.getMessage();

}

在生命周期注册与反注册事件监听,设置监听响应函数。

1

2

3private void getData() {

APIManager.getData();

}

需要请求可直接调用 API 管理中心提供的静态请求方法。

中心化管理 API,避免内存泄露,完美解耦

前两天实现了一个需求,在某一具体页面,发起网络请求后,无论用户是否还在发起请求页面,还是已经回退到之前的页面,只要请求响应,都需要在当前页面弹出一个 Dialog。

解耦发挥作用,只需要在全部页面(BaseActivity)注册监听这个请求的响应事件即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值