Java 如何从线程更新Android SQLite数据库而不访问上下文?
我正在开发一款Android应用程序。应用程序启动时首先要做的事情之一就是启动一个监听线程。此侦听线程打开平板电脑上其他应用程序的UDP套接字,并侦听其他应用程序发送数据。当我的侦听线程接收到数据时,我想将数据存储到SQLite数据库中,但如果不访问我的应用程序的上下文,我就不知道如何执行该操作 我有一个数据库助手应用程序:Java 如何从线程更新Android SQLite数据库而不访问上下文?,java,android,multithreading,sqlite,Java,Android,Multithreading,Sqlite,我正在开发一款Android应用程序。应用程序启动时首先要做的事情之一就是启动一个监听线程。此侦听线程打开平板电脑上其他应用程序的UDP套接字,并侦听其他应用程序发送数据。当我的侦听线程接收到数据时,我想将数据存储到SQLite数据库中,但如果不访问我的应用程序的上下文,我就不知道如何执行该操作 我有一个数据库助手应用程序: public class DatabaseHelper extends SQLiteOpenHelper { public DatabaseHelper(Conte
public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context){
super(context, "myAppDatabase.db", null, 1);
}
@Override
public void OnCreate(SQLiteDatabase db){
db.execSQL("CREATE TABLE ...");
}
@Override
public void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE ...");
}
// my database CRUD queries
}
这个DatabaseHelper类是我对数据库执行任何CRUD操作的唯一地方
我从MainActivity开始我的线程:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState){
ListenerClass myListenerClass = new ListenerClass();
Thread listenerThread = new Thread(myListenerClass);
listenerThread.setName("My Listener Thread");
listenerThread.start();
}
}
我有我的听众课:
public class ListenerClass implements Runnable {
private volatile boolean run = true;
private DataProcessingClass myDataProcessingClass;
@Override
public void run(){
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
// Open UDP socket
// Listen for data
// Process the data
myDatagramSocket.receive(myDatagramPacket);
byte[] data = myDatagramPacket.getData();
myDataProcessingClass = new DataProcessingClass();
myDataProcessingClass.processData(data);
}
public void setRun(boolean run){
this.run = run;
}
}
当我的侦听器线程接收到数据时,它调用另一个类来处理该数据,并将其存储到数据库中。它一直工作到我尝试将其存储到数据库中,因为我无法访问应用程序的上下文
有没有办法在不访问应用程序上下文的情况下写入SQLite数据库?如果没有,我如何才能获得此数据库写入的上下文?我通常使用的解决方案是添加一个构造函数,该构造函数接受
上下文。在这种特殊情况下,您需要向ListenerClass
和DataProcessingClass
添加这样的构造函数。ListenerClass
构造函数将给定的上下文
传递给DataProcessingClass
构造函数
或者,您可以像以前一样添加DataProcessingClass(Context)
构造函数,但改用ListenerClass(DataProcessingClass)
构造函数。这允许其他人先初始化DataProcessingClass
对象,这样ListenerClass
就不必担心如何初始化它。此外,这允许您进一步使用依赖项注入来初始化对象。(依赖项注入可能是一个比这个问题所需的更高级的主题。我只想提及它,以便您有兴趣的话可以进一步研究。)我通常使用的解决方案是添加一个构造函数,该构造函数采用上下文。在这种特殊情况下,您需要向ListenerClass
和DataProcessingClass
添加这样的构造函数。ListenerClass
构造函数将给定的上下文
传递给DataProcessingClass
构造函数
或者,您可以像以前一样添加DataProcessingClass(Context)
构造函数,但改用ListenerClass(DataProcessingClass)
构造函数。这允许其他人先初始化DataProcessingClass
对象,这样ListenerClass
就不必担心如何初始化它。此外,这允许您进一步使用依赖项注入来初始化对象。(依赖项注入可能是一个比这个问题所需的更高级的主题。我只想提及它,以便您可以在感兴趣的情况下进一步研究。)不幸的是,如果您没有访问上下文,我认为您将无法做到这一点
在这个方向上,我能给你的唯一建议是引入上下文作为线程的依赖项
我还想指出一些与体系结构相关的其他事情。在一般情况下,你的方法对于应用程序间的通信是完全有效的,但我认为对于Android来说,这有点不太理想
有几种方法可以利用开箱即用的组件为您完成繁重的工作。我想向您介绍一下ContentProviders
——它们非常适合在应用程序之间共享数据,并且将消除UDP连接的需要,处理线程,并将大大简化您的应用程序体系结构
另一种选择是利用意图
机制-您可以让应用程序A向应用程序B发送包含二进制数据的意图。应用程序B可以处理广播接收器中的意图,这将使您能够访问上下文
,并能够调用应用程序的其他组件,能够持久化结果数据。不幸的是,如果没有对上下文的访问,我认为您将无法做到这一点
在这个方向上,我能给你的唯一建议是引入上下文作为线程的依赖项
我还想指出一些与体系结构相关的其他事情。在一般情况下,你的方法对于应用程序间的通信是完全有效的,但我认为对于Android来说,这有点不太理想
有几种方法可以利用开箱即用的组件为您完成繁重的工作。我想向您介绍一下ContentProviders
——它们非常适合在应用程序之间共享数据,并且将消除UDP连接的需要,处理线程,并将大大简化您的应用程序体系结构
另一种选择是利用意图
机制-您可以让应用程序A向应用程序B发送包含二进制数据的意图。应用程序B可以处理广播接收器中的意图,这将使您能够访问上下文
,并能够调用应用程序的其他组件,能够持久化结果数据。您可以子类化并提供静态方法来获取应用程序上下文:
public class MyApplication extends Application {
private static Context sContext;
public static Context getContext() {
return sContext;
}
@Override
public void onCreate() {
super.onCreate();
sContext = this;
}
}
启动应用程序时,系统将构造应用程序
实例,并在创建任何活动、服务或接收者之前调用其onCreate()
(请参阅文档中有关Application.onCreate()
的注释)。因此,活动代码可以依赖于MyApplication.getContext()
始终返回有效的上下文
如果使用此方法,请记住还要更新清单中的应用程序名称:
<application
...
android:name="com.example.MyApplication" >