参考《第一行代码》——郭霖

回想这么久以来我们所学的内容,你会发现有很多地方都需要用到Context,弹出Toast的时候需要、启动活动的时候需要、发送广播的时候需要、操作数据库的时候需要、使用通知的时候需要等等等等。
或许目前你还没有为得不到Context而发愁过,因为我们很多的操作都是在活动中进行的,而活动本身就是一个Context对象。但是,当应用程序的架构逐渐开始复杂起来的时候,很多的逻辑代码都将脱离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 class 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;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {                ……
            }
        }).start();
    }

    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文件的<application>标签下进行指定就可以了,代码如下所示:

<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对象而发愁了

android#全局获取Context的技巧的更多相关文章

  1. 全局获取Context的技巧

    全局获取Context的技巧 在android开发中,非常多地方都要用到Context上下文这个类对象,比方:弹出 Toast 的时候须要.启动活动的时候须要.发送广播的时候须要.操作数据库的时候须要 ...

  2. Android开发之全局获取Context的技巧

    转自<第一行代码-Android>进阶篇 这本书对于入门来说确实很棒,很简单明了的介绍了Android开发中涉及到的方方面面,对我的帮助很大,同时记录一些该书中一些对我以后开发有用的东西, ...

  3. Android 全局获取 Context 与使用 Intent 传递对象

    =====================全局获取 Context======================== Android 开发中很多地方需要用到 Context,比如弹出 Toast.启动活 ...

  4. 全局获取Context的技巧(再也不要为获取Context而感到烦恼)

    1.Context概念 Context,相信不管是第一天开发Android,还是开发Android的各种老鸟,对于Context的使用一定不陌生~~你在加载资源.启动一个新的Activity.获取系统 ...

  5. Android 如何全局获取Context

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

  6. 全局获取Context

    1.定制一个Application类,管理全局的状态信息 public class MyApplication extends Application{ private static Context ...

  7. Android各种获取Context方法

    首先讲一讲这四个函数的区别,后面还有我对context的一些理解区别如下所示: 原文链接http://stackoverflow.com/questions/6854265/getapplicatio ...

  8. Android 获取全局Context的技巧

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

  9. Android-获取全局Context的技巧-android学习之旅(68)

    我们经常需要获取全局的Context ,比如弹出Toast,启动活动,服务,接收器,还有自定义控件,操作数据库,使用通知等 通常的方法是在调用的地方传入Context参数 ,有时候这种不会奏效,教给大 ...

随机推荐

  1. Idea中Module is not specified解决办法

    打开idea,想跑一个类,但是,给我报了一个红叉: 当我点击run的时候,弹出来一个框: “Error:Module not specified”  Module 未指定 “这个原因是项目文件夹有修改 ...

  2. IE的F12开发人员工具不显示 转载自:http://blog.csdn.net/longyulu/article/details/8749705

    IE的F12开发人员工具不显示问题: 按下F12之后,开发人员工具在桌面上看不到,但是任务栏里有显示.将鼠标放在任务栏的开发人员工具上,出现一片透明的区域,选中之后却出不来.将鼠标移动到开发人员工具的 ...

  3. [React] Reduce Code Redundancy with Custom React Hooks

    In this lesson, we'll cover how to create a custom React hook for managing the state of any input. T ...

  4. Visual Studio 2019 激活

    Visual Studio 2019 Enterprise 企业版:BF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 Professional 专业版: ...

  5. could not load file or assembly "System.Web.Mvc...

    1.一般出现这个错误是因为Web.Config里面的版本号跟project用到的dll版本对应不上 更改webconfig <add assembly="System.Web.Mvc, ...

  6. Eclise快捷键(最全)

    Eclipse常用快捷键 Eclipse常用快捷键 1几个最重要的快捷键 代码助手:Ctrl+Space(简体中文操作系统是Alt+/) 快速修正:Ctrl+1 单词补全:Alt+/ 打开外部Java ...

  7. 第四章 Python数据分析-描述性分析

    Python基础统计 统计函数:describe() 常用的统计指标函数: 统计函数 注释 (@数据分析-jacky) size 计算 sum 求和 mean 平均值 var 方差 std 标准差

  8. deepin Linux 日常命令、插件、方法等汇总【更新中】

    查看系统编码: dawn@dawn-PC:~$ locale LANG=zh_CN.UTF- LANGUAGE=zh_CN LC_CTYPE="zh_CN.UTF-8" LC_NU ...

  9. codeforces#1166F. Vicky's Delivery (Service并查集+启发式合并)

    题目链接: https://codeforces.com/contest/1166/problem/F 题意: 给出节点数为$n$,边数为$m$的图,保证每个点对都是互连的 定义彩虹路:这条路经过$k ...

  10. Java基础_通过模拟售票情景解决线程不安全问题

    用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线程表示 第一种方法:通过继承Thread类的方法创建线程 package com.Gary1; publi ...