【问题标题】:ROOM Framework crashes an applicationROOM 框架使应用程序崩溃
【发布时间】:2019-12-10 11:33:33
【问题描述】:

我在网上有一些关于 ROOM Framework 的教程。

我已经创建了用户类

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) 

谁能告诉我那里有什么问题?

【问题讨论】:

  • 你的MainActivity 在哪里。也发一下。问题出在那儿

标签: java android android-room


【解决方案1】:

问题就在这里。

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

您在初始化活动类时调用它。 Activity 类不是普通的 java 类,它需要大量的继承——主要是Base context。调用super.onCreate() 方法后,基本上下文可用。

你有两个选择。

  1. 在您的应用程序类'onCreate() 中移动数据库初始化并使用单例实例来访问数据库。
  2. 在您的活动的onCreate() 方法中初始化它。

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

【讨论】:

    【解决方案2】:

    我的 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();
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      [编辑] 遵循此代码:

      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() 方法中访问系统服务。这将解决您的问题。 此外,错误不是因为 Room。

      【讨论】:

      • 那为什么如果我删除:UsersDatabase usersDatabase = Room.databaseBuilder(this, UsersDatabase.class, "users") .allowMainThreadQueries() .build(); UserDAO userDAO = usersDatabase.getUserDAO();列表 用户 = userDAO.getUsers(); System.out.println(用户);启动项();从我的应用程序正常工作的代码来看?
      • 崩溃的同样问题是当我将完整代码从 ROOM 从 MainActivity 移动到例如RegisterActivity 所以我的应用程序正在启动,但是当我想移动到 RegisterActivity 时它会中断。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-12
      • 1970-01-01
      • 1970-01-01
      • 2012-01-28
      • 2020-01-07
      • 1970-01-01
      相关资源
      最近更新 更多