如何在全局获取Context

转载 2015年07月06日 16:36:25

在我们写代码的过程中,经常会用到Context,如弹出toast的时候,启动活动,发送广播的时候等等。
当应用层序的架构逐渐开始复杂起来的时候,很多的逻辑代码都将脱离Activity类,而此时我们又恰恰需要使用Context,举个例子来说,当我们写了一个HttpUtil类时,里面是对一些通用的网络操作进行了封装,代码如下:

public class HttpUtil {

    public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                try {
                    URL url = new URL(address);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    InputStream in = connection.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    if (listener != null) {
                        listener.onFinish(response.toString());
                    }
                } catch (Exception e) {
                    if (listener != null) {
                        listener.onError(e);
                    }
                } finally {
                    if (connection != null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

}

这里使用sendHttpRequest()方法来发送HTTP请求显然是没有问题的,并且我们还可以在回调方法中处理服务器返回的数据。但现在我们想对sendHttpRequest()方法进行一些优化,当检测到网络不存在的时候就给用户一个Toast提示,并且不再执行后面的代码。看似一个挺简单的功能,可是却存在一个让人头疼的问题,弹出Toast提示需要一个Context参数,而我们在HttpUtil类中显然是获取不到Context对象的,这该怎么办呢?
其实要想快速解决这个问题也很简单,大不了在sendHttpRequest()方法中添加一个Context参数就行了嘛,于是可以将HttpUtil中的代码进行如下修改:

public static void sendHttpRequest(final Context context,
            final String address, final HttpCallbackListener listener) {
        if (!isNetworkAvailable()) {
            Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show();
            return;
        }
private static boolean isNetworkAvailable() {
        ……
    }

可以看到,这里在方法中添加了一个Context参数,并且假设有一个isNetworkAvailable()方法用于判断当前网络是否可用,如果网络不可用的话就弹出Toast提示,并将方法return掉。
虽说这也确实是一种解决方案,但是却有点推卸责任的嫌疑,因为我们将获取Context的任务转移给了sendHttpRequest()方法的调用方,至于调用方能不能得到Context对象,那就不是我们需要考虑的问题了。
由此可以看出,在某些情况下,获取Context并非是那么容易的一件事,有时候还是挺伤脑筋的。不过别担心,下面我们就来学习一种技巧,让你在项目的任何地方都能够轻松获取到Context。
Android提供了一个Application类,每当应用程序启动的时候,系统就会自动将这个类进行初始化。而我们可以定制一个自己的Application类,以便于管理程序内一些全局的状态信息,比如说全局Context。
定制一个自己Application其实并不复杂,首先我们需要创建一个MyApplication类继承自Application,代码如下所示:

public class MyApplication extends Application {

    private static Context context;
    @Override
    public void onCreate() {
        context = getApplicationContext();
    }

    public static Context getContext() {
        return context;
    }

}

可以看到,MyApplication中的代码非常简单。这里我们重写了父类的onCreate()方法,并通过调用getApplicationContext()方法得到了一个应用程序级别的Context,然后又提供了一个静态的getContext()方法,在这里将刚才获取到的Context进行返回。
接下来我们需要告知系统,当程序启动的时候应该初始化MyApplication类,而不是默认的Application类。这一步也很简单,在AndroidManifest.xml文件的标签下进行指定就可以了,代码如下所示:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.networktest"
    android:versionCode="1"
    android:versionName="1.0" >
    ……
    <application
        android:name="com.example.networktest.MyApplication"
        …… >
        ……
    </application>
</manifest>

注意这里在指定MyApplication的时候一定要加上完整的包名,不然系统将无法找到这个类。
这样我们就已经实现了一种全局获取Context的机制,之后不管你想在项目的任何地方使用Context,只需要调用一下MyApplication.getContext()就可以了。
那么接下来我们再对sendHttpRequest()方法进行优化,代码如下所示:

public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
    if (!isNetworkAvailable()) {
        Toast.makeText(MyApplication.getContext(), "network is unavailable",
                Toast.LENGTH_SHORT).show();
                return;
    }
    ……
}

可以看到,sendHttpRequest()方法不需要再通过传参的方式来得到Context对象,而只需调用一下MyApplication.getContext()方法就可以了。有了这个技巧,你再也不用为得不到Context对象而发愁了。

以上内容转载《第一行代码》

相关文章推荐

如何在项目的任何地方轻松获取到全局状态信息Context

如何在项目的任何地方都轻松获取到 Context? 答案:Android 提供了一个 Application 类,每当应用程序启动的时候,系统就会自动将这个类进行初始化。        我们定制一...

android全局获取Context对象(在静态函数中实现toast)

全局获取Context对象的意义: 当应用程序的架构逐渐复杂起来的时候,很多逻辑代码都将脱离Activity或者Service,但是如果此时你又恰恰需要使用Context,这个时候就需要用到全局获取...

Android 如何全局获取Context

有时,在处理业务逻辑的时候,需要Context对象,但在某些情况下,并非容易获取,这时就需要一些巧妙的手段来管理Context。     在Android中,提供了一个类Application,...

全局获取Context的技巧

本文摘自《第一行代码》,很有用处,分享下。

全局获取Context的技巧,使用intent来传递对象

举例获得Context 例如我们编写了一个HttpUtil类,然后封装了起来 public class HttpUtil{ public static void sendHttpReq...

Android中获取全局的Context技巧

在我们平常的开发中,很多时候我们新建的一个普通的java类文件(非Activity类的),在某些地方我们需要用到Context,弹出Toast的时候要、启动活动的时候要、发送广播的时候要、操作数据库和...

安卓开发:全局获取Context的技巧

回想这么久所学的内容,你会发现很多地方都需要用到Context,弹出Toast的时候,启动活动的时候,发送广播的时候,操作数据库的时候,使用通知的时候等等。。。 或许目前你还没有为得不到Contex...

Android全局变量和Context

  • 2016年12月19日 22:23
  • 170KB
  • 下载

Android 全局获取Context(随时随地的使用Context)

参考:《第一行代码》第13章 ##################################################### 很多地方都需要使用Context,弹出To...

Android关于context上下文定义全局的

01. 05.
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何在全局获取Context
举报原因:
原因补充:

(最多只允许输入30个字)