美文网首页Android进阶之路Android技术知识
Framework系统资源——Context的使用与族谱分析

Framework系统资源——Context的使用与族谱分析

作者: 码农的地中海 | 来源:发表于2022-07-13 22:08 被阅读0次

    Context定义

    Android应用都是使用Java语言来编写的,本质上也是一个对象,那么Activity可以new吗?一个Android程序和一个Java程序,他们最大的区别在哪里?划分界限又是什么呢?其实简单点分析,Android程序不像Java程序一样,随便创建一个类,写个main()方法就能跑了,Android应用模型是基于Activity、Service、BroadcastReceiver等组件的应用设计模式,组件的运行要有一个完整的Android工程环境,在这个环境下,这些组件并不是像一个普通的Java对象new一下就能创建实例的了,而是要有它们各自的上下文环境Context。可以这样讲,Context是维持Android程序中各组件能够正常工作的一个核心功能类。


    45c636374234e194de7924b083475052.jpeg

    什么是Context

    /**
    
     * Interface to global information about an application environment.  This is
    
     * an abstract class whose implementation is provided by
    
     * the Android system.  It
    
     * allows access to application-specific resources and classes, as well as
    
     * up-calls for application-level operations such as launching activities,
    
     * broadcasting and receiving intents, etc.
     */
    public abstract class Context {
        /**
         * File creation mode: the default mode, where the created file can only
         * be accessed by the calling application (or all applications sharing the
         * same user ID).
         * @see #MODE_WORLD_READABLE
         * @see #MODE_WORLD_WRITEABLE
         */
        public static final int MODE_PRIVATE = 0x0000;
        
        public static final int MODE_WORLD_WRITEABLE = 0x0002;
    
        public static final int MODE_APPEND = 0x8000;
    
        public static final int MODE_MULTI_PROCESS = 0x0004;
    
        }
    
    

    以上是Android源码对Context的描述:

    • 它是应用程序环境的全局信息的接口。
    • 这是一个抽象类,由Android系统提供。
    • 它允许访问特定于应用程序的资源和类,以及调用应用程序级操作,如启动活动,广播和接收意图等。

    Context作用的具体体现

    有了Context这个环境,Android组件才可以正常被创建和调用,所以Context的作用如下:
    
    TextView tv = new TextView(getContext());
    
    ListAdapter adapter = new SimpleCursorAdapter(getApplicationContext(), ...);
    
    AudioManager am = (AudioManager) getContext().
    getSystemService(Context.AUDIO_SERVICE);
    
    getApplicationContext().getSharedPreferences(name, mode);
    
    getApplicationContext().getContentResolver().query(uri, ...);
    
    getContext().getResources().getDisplayMetrics().widthPixels * 5 / 8;
    
    getContext().startActivity(intent);
    
    getContext().startService(intent);
    
    getContext().sendBroadcast(intent);
    

    Context类的族谱

    image.png

    从图中可以看出,Activtiy、Service、Application的最基类都是Context。


    image.png

    Context其实就是提供了一个代码执行的环境,比如Activity,就是提供了Activity中代码的执行环境,因此它持有着该环境中的所有成员信息和函数。

    context使用

    context相关函数

    //返回一个空 context, 这只能用于高等级(在 main 或顶级请求中),作为context的根节点
    context.Background() Context
    //返回一个空的 context,不知道用什么的时候就上这个
    context.TODO() Context
    context.WithValue(parent Context, key, val interface{}) (ctx Context, cancel CancelFunc)
    context.WithCancel(parent Context) (ctx Context, cancel CancelFunc)
    context.WithDeadline(parent Context, d time.Time) (ctx Context, cancel CancelFunc)
    context.WithTimeout(parent Context, timeout time.Duration) (ctx Context, cancel CancelFunc)
    

    context相关使用

    Done方法取消

    func Stream(ctx context.Context, out chan<- Value) error {
        for {
            v, err := DoSomething(ctx)
            if err != nil {
                return err
            }
            select {
            case <-ctx.Done():
                return ctx.Err()
            case out <- v:
            }
        }
    }
    

    WithValue传值

    func main() {
        ctx, cancel := context.WithCancel(context.Background())
        valueCtx := context.WithValue(ctx, key, "add value")
        go watch(valueCtx)
        time.Sleep(10 * time.Second)
        cancel()
        time.Sleep(5 * time.Second)
    }
     
    func watch(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                //get value
                fmt.Println(ctx.Value(key), "is cancel")
                return
            default:
                //get value
                fmt.Println(ctx.Value(key), "int goroutine")
                time.Sleep(2 * time.Second)
            }
        }
    }
    

    WithTimeout超时取消

    package main
     
    import (
        "fmt"
        "sync"
        "time"
        "golang.org/x/net/context"
    )
    var (
        wg sync.WaitGroup
    )
    func work(ctx context.Context) error {
        defer wg.Done()
        for i := 0; i < 1000; i++ {
            select {
            case <-time.After(2 * time.Second):
                fmt.Println("Doing some work ", i)
            // we received the signal of cancelation in this channel
            case <-ctx.Done():
                fmt.Println("Cancel the context ", i)
                return ctx.Err()
            }
        }
        return nil
    }
     
    func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
        defer cancel()
        fmt.Println("Hey, I'm going to do some work")
        wg.Add(1)
        go work(ctx)
        wg.Wait()
        fmt.Println("Finished. I'm going home")
    }
    

    WithDeadline截止时间

    package main
    import (
        "context"
        "fmt"
        "time"
    )
    func main() {
        d := time.Now().Add(1 * time.Second)
        ctx, cancel := context.WithDeadline(context.Background(), d)
        defer cancel()
        select {
        case <-time.After(2 * time.Second):
            fmt.Println("oversleep")
        case <-ctx.Done():
            fmt.Println(ctx.Err())
        }
    }
    

    文末

    一个Activity就是一个Context,一个Service也是一个Context。Android程序员把“场景”抽象为Context类,他们认为用户和操作系统的每一次交互都是一个场景,比如打电话、发短信,这些都是一个有界面的场景,还有一些没有界面的场景,比如后台运行的服务(Service)。更多framework学习进阶;带你学习framework深层技术。

    一个应用程序可以认为是一个工作环境,用户在这个环境中会切换到不同的场景,这就像一个前台秘书,她可能需要接待客人,可能要打印文件,还可能要接听客户电话,而这些就称之为不同的场景,前台秘书可以称之为一个应用程序。

    相关文章

      网友评论

        本文标题:Framework系统资源——Context的使用与族谱分析

        本文链接:https://www.haomeiwen.com/subject/xxntirtx.html