Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从线程更新Android SQLite数据库而不访问上下文?_Java_Android_Multithreading_Sqlite - Fatal编程技术网

Java 如何从线程更新Android SQLite数据库而不访问上下文?

Java 如何从线程更新Android SQLite数据库而不访问上下文?,java,android,multithreading,sqlite,Java,Android,Multithreading,Sqlite,我正在开发一款Android应用程序。应用程序启动时首先要做的事情之一就是启动一个监听线程。此侦听线程打开平板电脑上其他应用程序的UDP套接字,并侦听其他应用程序发送数据。当我的侦听线程接收到数据时,我想将数据存储到SQLite数据库中,但如果不访问我的应用程序的上下文,我就不知道如何执行该操作 我有一个数据库助手应用程序: public class DatabaseHelper extends SQLiteOpenHelper { public DatabaseHelper(Conte

我正在开发一款Android应用程序。应用程序启动时首先要做的事情之一就是启动一个监听线程。此侦听线程打开平板电脑上其他应用程序的UDP套接字,并侦听其他应用程序发送数据。当我的侦听线程接收到数据时,我想将数据存储到SQLite数据库中,但如果不访问我的应用程序的上下文,我就不知道如何执行该操作

我有一个数据库助手应用程序:

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" >