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

2016-12-08 11:44:09 +08:00
Duluku  Duluku

想写一个 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);
}
10085 次点击
所在节点   Android  Android
20 条回复
viator42
viator42
2016-12-08 11:47:00 +08:00
定义 Application 类不就行了
Duluku
Duluku
2016-12-08 11:48:32 +08:00
@viator42 不是很明白诶,能详细说一下吗? 谢谢
1023400273
1023400273
2016-12-08 11:48:39 +08:00
直接在 Application 内搞定
Duluku
Duluku
2016-12-08 11:52:15 +08:00
@1023400273 怎么在 Application 内搞定嘞。。不是特别明白。。。多谢回复 :)
1023400273
1023400273
2016-12-08 11:57:18 +08:00
数据库类做成一个单例,在 Application 内初始化
q397064399
q397064399
2016-12-08 12:02:56 +08:00
shanjinwei
shanjinwei
2016-12-08 12:03:46 +08:00
…为什么不写个 application 弄个单例
Duluku
Duluku
2016-12-08 12:08:18 +08:00
@q397064399 链接帮大忙了,多谢多谢
Chrisplus
Chrisplus
2016-12-08 12:20:37 +08:00
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
Duluku
2016-12-08 12:27:41 +08:00
@Chrisplus 我好像明白了,可以这么理解吗,如果这个 Sqlite 我传的 Context 是某个 Activity ,那么这个 Activity 要是被销毁,这个 dbHelper 会被销毁掉, 但是如果这个 Sqlite 我传的 getApplicationContext 的话,这个 dbHelper 是基于 Application 的,所以直到 App 被销毁才是被销毁。 所以这里只能使用 getApplicationContext 。
Duluku
Duluku
2016-12-08 12:29:34 +08:00
@Chrisplus 顺便想问问另一个细节,我想在某个线程里 Toast , 这里的 Context 应该怎么获取呢? 要么是从之前的 Activity 或者 Service 传过来,还是有别的办法? :)
zhaohui318
zhaohui318
2016-12-08 13:14:46 +08:00
@Duluku 反了,如果你拿的是 activitycontext ,因为你的静态类不会销毁导致 activity 也不会销毁,这就出现了内存泄漏,静态类是和 application 一样的生命周期,所以需要用 applicationcontext
zhaohui318
zhaohui318
2016-12-08 13:27:49 +08:00
@Duluku toast 也可以使用 applicationcontext 吧
Chrisplus
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
2016-12-08 13:35:44 +08:00
用 Realm 替代 SQLite.
Duluku
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
2016-12-08 13:39:07 +08:00
singleton?
Duluku
2016-12-08 13:42:07 +08:00
@Chrisplus @zhaohui318 多谢多谢,你的回复对我很有帮助
JayFang1993
2016-12-08 18:54:54 +08:00
有些地方还必须要当前页面 Activity 的 context 比如弹对话框
Duluku
2016-12-08 19:02:54 +08:00
@JayFang1993 没错没错,这个时候的 Context 必须要传下去的... :)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/326134

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX