V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Duluku
V2EX  ›  Android

[菜鸟询问]单独建一个 Activity 提供 Context 合适吗?

  •  1
     
  •   Duluku · 2016-12-08 11:44:09 +08:00 · 8574 次点击
    这是一个创建于 2910 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想写一个 SQLite 的小项目,我想在任何线程地方直接对数据库进行修改,想做个静态对象。测试发现只有最开始创建 Helper 的时候用到了 Context ,所以有两种方法。

    1. 第一种,在程序最开始就在 Activity 中调用一次getWritableDatabase然后以后就可以应该就不用 Context 了
    2. 第二种,单独建一个 Activity 提供 Context ,这样也解决很多其他的问题,比如某线程内使用 Toast ,但是总觉得这种方式不太好。

    望各位 V 友指教 Orz

    ps. 其实就是对 Context 这种东西不是很熟,各位是怎么用的?

    private static MyDatabaseHelper dbHelper = null;//静态对象引用
    
    public static MyDatabaseHelper getInstance(Context context) {
    	if (dbHelper == null) {
    		Log.i(TAG, "getInstance: 创建 helper");
         // 发现只有最开始创建的时候使用了 Context ,以后也不会再用了。   
    		dbHelper = new MyDatabaseHelper(context);
    	}
    	return dbHelper;
    }
    
    private MyDatabaseHelper(Context context) {
    	super(context, DB_NAME, null, VERSION);
    }
    
    第 1 条附言  ·  2016-12-08 12:39:24 +08:00
    顺便想问问另一个细节,我想在某个线程里 Toast , 这里的 Context 应该怎么获取呢? 要么是从之前的 Activity 或者 Service 传过来,还是有别的办法? :)
    20 条回复    2016-12-08 19:02:54 +08:00
    viator42
        1
    viator42  
       2016-12-08 11:47:00 +08:00   ❤️ 1
    定义 Application 类不就行了
    Duluku
        2
    Duluku  
    OP
       2016-12-08 11:48:32 +08:00
    @viator42 不是很明白诶,能详细说一下吗? 谢谢
    1023400273
        3
    1023400273  
       2016-12-08 11:48:39 +08:00   ❤️ 1
    直接在 Application 内搞定
    Duluku
        4
    Duluku  
    OP
       2016-12-08 11:52:15 +08:00
    @1023400273 怎么在 Application 内搞定嘞。。不是特别明白。。。多谢回复 :)
    1023400273
        5
    1023400273  
       2016-12-08 11:57:18 +08:00
    数据库类做成一个单例,在 Application 内初始化
    shanjinwei
        7
    shanjinwei  
       2016-12-08 12:03:46 +08:00 via Android   ❤️ 1
    …为什么不写个 application 弄个单例
    Duluku
        8
    Duluku  
    OP
       2016-12-08 12:08:18 +08:00
    @q397064399 链接帮大忙了,多谢多谢
    Chrisplus
        9
    Chrisplus  
       2016-12-08 12:20:37 +08:00   ❤️ 1
    Context.getApplicationContext()
    额外贴一段 Android Developer Blog 里的话

    In summary, to avoid context-related memory leaks, remember the following:

    - Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
    - Try using the context-application instead of a context-activity
    - Avoid non-static inner classes in an activity if you don't control their life cycle, use a static inner class and make a weak reference to the activity inside. The solution to this issue is to use a static inner class with a WeakReference to the outer class, as done in ViewRoot and its W inner class for instance
    - A garbage collector is not an insurance against memory leaks
    Duluku
        10
    Duluku  
    OP
       2016-12-08 12:27:41 +08:00
    @Chrisplus 我好像明白了,可以这么理解吗,如果这个 Sqlite 我传的 Context 是某个 Activity ,那么这个 Activity 要是被销毁,这个 dbHelper 会被销毁掉, 但是如果这个 Sqlite 我传的 getApplicationContext 的话,这个 dbHelper 是基于 Application 的,所以直到 App 被销毁才是被销毁。 所以这里只能使用 getApplicationContext 。
    Duluku
        11
    Duluku  
    OP
       2016-12-08 12:29:34 +08:00
    @Chrisplus 顺便想问问另一个细节,我想在某个线程里 Toast , 这里的 Context 应该怎么获取呢? 要么是从之前的 Activity 或者 Service 传过来,还是有别的办法? :)
    zhaohui318
        12
    zhaohui318  
       2016-12-08 13:14:46 +08:00
    @Duluku 反了,如果你拿的是 activitycontext ,因为你的静态类不会销毁导致 activity 也不会销毁,这就出现了内存泄漏,静态类是和 application 一样的生命周期,所以需要用 applicationcontext
    zhaohui318
        13
    zhaohui318  
       2016-12-08 13:27:49 +08:00   ❤️ 1
    @Duluku toast 也可以使用 applicationcontext 吧
    Chrisplus
        14
    Chrisplus  
       2016-12-08 13:33:47 +08:00
    @Duluku
    1. 参考楼上,你的理解反了。
    2. Toast 应该与 application context 绑定,参考 google 的 sample code

    https://developer.android.com/guide/topics/ui/notifiers/toasts.html#CustomToastView

    Context context = getApplicationContext();
    CharSequence text = "Hello toast!";
    int duration = Toast.LENGTH_SHORT;

    Toast toast = Toast.makeText(context, text, duration);
    toast.show();
    xingda920813
        15
    xingda920813  
       2016-12-08 13:35:44 +08:00
    用 Realm 替代 SQLite.
    Duluku
        16
    Duluku  
    OP
       2016-12-08 13:38:30 +08:00
    @zhaohui318 是的,我明白了! 类似这么写就好了,所有的 Context 也解决了。以后还是要认真对待这个 Context ,不能乱传呀
    ```
    public class CustomApplication extends Application {

    private static MyDatabaseHelper myDatabaseHelper;
    private static Context context;

    public static Context getContext() {
    return context;
    }

    public static MyDatabaseHelper getMyDatabaseHelper() {
    return myDatabaseHelper;
    }

    @Override
    public void onCreate()
    {
    super.onCreate();
    myDatabaseHelper = new MyDatabaseHelper(getApplicationContext());
    context = getApplicationContext();
    }

    }
    ```
    bazingaterry
        17
    bazingaterry  
       2016-12-08 13:39:07 +08:00
    singleton?
    Duluku
        18
    Duluku  
    OP
       2016-12-08 13:42:07 +08:00
    @Chrisplus @zhaohui318 多谢多谢,你的回复对我很有帮助
    JayFang1993
        19
    JayFang1993  
       2016-12-08 18:54:54 +08:00
    有些地方还必须要当前页面 Activity 的 context 比如弹对话框
    Duluku
        20
    Duluku  
    OP
       2016-12-08 19:02:54 +08:00
    @JayFang1993 没错没错,这个时候的 Context 必须要传下去的... :)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3561 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 10:48 · PVG 18:48 · LAX 02:48 · JFK 05:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.