ROOM Framework使应用程序崩溃

时间:2019-12-10 11:33:33

标签: java android android-room

我已经在Internet上使用ROOM Framework学习了一些教程。

我已经建立了User类

package com.example.mountaintraveller;

import androidx.annotation.NonNull;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity (tableName = "users")
public class User{
    @PrimaryKey
    @NonNull private long Id;
    private String name;
    private String email;
    private String password;

    public long getId(){
        return Id;
    }
    public void setId(long Id){ this.Id = Id; }

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }

    public String getEmail(){
        return email;
    }
    public void setEmail(String email){
        this.email = email;
    }

    public String getPassword(){
        return password;
    }
    public void setPassword(String password){
        this.password = password;
    }
}

UserDAO界面:

package com.example.mountaintraveller;


import java.util.List;

import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

@Dao
public interface UserDAO {
    @Insert
    void insert(User... users);

    @Update
    void update(User... users);

    @Delete
    void delete(User user);

    @Query("SELECT * FROM users")
    List<User> getUsers();

    @Query("SELECT COUNT(*) FROM users")
    int countUsers();
}

和UserDatabase类:

package com.example.mountaintraveller;


import android.content.Context;

import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;

@Database(entities = {User.class}, version = 1)
public abstract class UsersDatabase extends RoomDatabase {

    public abstract UserDAO getUserDAO();
    private static UsersDatabase INSTANCE;

    public static UsersDatabase getUsersDatabase(Context context){
        if(INSTANCE == null){
            INSTANCE =
                    Room.databaseBuilder(context.getApplicationContext(), UsersDatabase.class, "users")
                    .allowMainThreadQueries()
                    .build();
        }
        return INSTANCE;
    }

    public static void destroyInstance(){
        INSTANCE = null;
    }
}

当我尝试在我的应用程序中运行它时: RegisterActivity.class:

UserDAO userDao = UsersDatabase.getUsersDatabase(getApplicationContext()).getUserDAO();
User user = new User();
[...]
user.setName(tietReg_Username.toString().trim());
user.setEmail(tietReg_Email.toString().trim());
user.setPassword(tietReg_Pwd.toString().trim());
userDao.insert(user);

其中tietReg_Username,tierReg_Email和tietReg_Pwd是TextInputEditText(我将其转换为字符串) 我也有MainActivity.class和命令

List<User> users = userDAO.getUsers();
System.out.println(users);

我要查看是否有任何用户注册的地方。

实际上我的应用程序未运行(应用程序不断停止),其中包含以下信息:


E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.mountaintraveller, PID: 4881
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.mountaintraveller/com.example.mountaintraveller.MainActivity}: java.lang.IllegalStateException: System services not available to Activities before onCreate()
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2843)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
        at android.app.Activity.getSystemService(Activity.java:6014)
        at androidx.room.RoomDatabase$JournalMode.resolve(RoomDatabase.java:517)
        at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:943)
        at com.example.mountaintraveller.MainActivity.<init>(MainActivity.java:53)
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:41)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1215)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2831)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

有人可以告诉我那里有什么问题吗?

3 个答案:

答案 0 :(得分:2)

问题出在这里。

UsersDatabase usersDatabase = Room.databaseBuilder(this, UsersDatabase.class, "users")
        .allowMainThreadQueries()
        .build();

您在初始化活动类时正在调用它。活动类不是常规的Java类,它需要大量继承-主要是Base context。在调用super.onCreate()方法之后,基本上下文才可用。

您有2个选择。

  1. 在应用程序类的onCreate()中移动数据库初始化,并使用单例实例访问数据库。
  2. 通过您的活动的onCreate()方法对此进行初始化。

理想情况下,您应该使用单例实例,因为您无需创建数据库的多个实例。

答案 1 :(得分:0)

我的MainActivity.class:

public class MainActivity extends Activity {
    private final Activity activity = MainActivity.this;
    [...]
    UsersDatabase usersDatabase = Room.databaseBuilder(this, UsersDatabase.class, "users")
            .allowMainThreadQueries()
            .build();
    UserDAO userDAO = usersDatabase.getUserDAO();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Context ctx = getApplicationContext();
        Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));

        setContentView(R.layout.activity_main);

        map = (MapView)findViewById(R.id.map);
        map.setTileSource(TileSourceFactory.MAPNIK);
        map.setBuiltInZoomControls(true);
        map.setMultiTouchControls(true);
        IMapController mapController = map.getController();
        mapController.setZoom(11.5);
        GeoPoint newPoint = new GeoPoint(49.10, 20.08);
        mapController.setCenter(newPoint);



        launchItems();
}
private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent;
            switch (view.getId()) {
                [...]
                case R.id.btnMain_Login:
                    // #TODO: Login here.
                    List<User> users = userDAO.getUsers();
                    System.out.println(users);

                    break;
                default:
                    break;
            }
        }
    };

    public void onResume(){
        super.onResume();
        map.onResume();
    }
    public void onPause(){
        super.onPause();
        map.onPause();
    }

}

答案 2 :(得分:0)

[编辑] 请遵循以下代码:

public class MainActivity extends Activity {
    private final Activity activity = MainActivity.this;
    [...]


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Context ctx = getApplicationContext();
        Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));

        setContentView(R.layout.activity_main);

        map = (MapView)findViewById(R.id.map);
        map.setTileSource(TileSourceFactory.MAPNIK);
        map.setBuiltInZoomControls(true);
        map.setMultiTouchControls(true);
        IMapController mapController = map.getController();
        mapController.setZoom(11.5);
        GeoPoint newPoint = new GeoPoint(49.10, 20.08);
        mapController.setCenter(newPoint);


UsersDatabase usersDatabase = Room.databaseBuilder(this, UsersDatabase.class, "users")
            .allowMainThreadQueries()
            .build();
    UserDAO userDAO = usersDatabase.getUserDAO();

        launchItems();
}
private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent;
            switch (view.getId()) {
                [...]
                case R.id.btnMain_Login:
                    // #TODO: Login here.
                    List<User> users = userDAO.getUsers();
                    System.out.println(users);

                    break;
                default:
                    break;
            }
        }
    };

    public void onResume(){
        super.onResume();
        map.onResume();
    }
    public void onPause(){
        super.onPause();
        map.onPause();
    }

}

该错误在您的活动文件中。 错误:

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.mountaintraveller/com.example.mountaintraveller.MainActivity}: java.lang.IllegalStateException: System services not available to Activities before onCreate()

表示您正在尝试在调用onCreate()之前创建系统服务。尝试在onCreate()方法中访问系统服务。这样可以解决您的问题。 另外,该错误不是由于房间造成的。