我正在尝试用MVVM模式的登录活动创建一个初始屏幕。我的闪屏确实工作得很好,但当它试图完成并启动LoginActivity时,应用程序崩溃了。我得到如下错误。
请帮我解决这个问题。我需要在我的项目中有一个slapsh屏幕,其中包含MVVM模式和LoginActive的房间db。非常欢迎解释或代码示例。
我的Splash活动
public class SplashActivity extends AppCompatActivity {
public void onAttachedToWindow() {
super.onAttachedToWindow();
Window window = getWindow();
window.setFormat(PixelFormat.RGBA_8888);
}
/**
* Called when the activity is first created.
*/
Thread splashTread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
StartAnimations();
}
private void StartAnimations() {
Animation anim = AnimationUtils.loadAnimation(this, R.anim.alpha);
anim.reset();
LinearLayout l = findViewById(R.id.splash_layout);
l.clearAnimation();
l.startAnimation(anim);
anim = AnimationUtils.loadAnimation(this, R.anim.translate);
anim.reset();
ImageView iv = findViewById(R.id.splash);
iv.clearAnimation();
iv.startAnimation(anim);
splashTread = new Thread() {
@Override
public void run() {
try {
int waited = 0;
// Splash screen pause time
while (waited < 3500) {
sleep(100);
waited += 100;
}
Intent intent = new Intent(SplashActivity.this,
LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
SplashActivity.this.finish();
} catch (InterruptedException e) {
// do nothing
} finally {
SplashActivity.this.finish();
}
}
};
splashTread.start();
}
}
我的登录活动
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
private View mProgressView;
private View mLoginFormView;
private ActivityLoginBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
ActivityLoginBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
//get the view model
loginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
binding.setUser(loginViewModel);
// The observer updates the UI when Login Operation is successful
loginViewModel.getUser().observe(this, userResponse -> {
if (userResponse != null) {
Toast.makeText(LoginActivity.this, "Login success", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
} else {
Log.d("LoginActivity", "value user is null");
// Show ERROR
}
});
binding.loginButton.setOnClickListener (
(
View view) ->
{
loginViewModel.onBtnLoginClick();
});
}
/**
* Shows the progress UI and hides the login form.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
}
}
我的登录查看模型
public class LoginViewModel extends ViewModel {
private boolean errorMsg = true;
private Validations validations;
// Create a LiveData
private LiveData<User> userResponse;
public static final ObservableField<String> username = new ObservableField<>();
public static final ObservableField<String> password = new ObservableField<>();
public static final ObservableField<String> errorUsername = new ObservableField<>();
public static final ObservableField<String> errorPassword = new ObservableField<>();
private UserRepository userRepository;
public LoginViewModel(Context mContext) {
userRepository = new UserRepository(mContext);
username.set("ccuser");
password.set("67890");
userResponse = userRepository.getUser();
validations=new Validations();
}
public LiveData<User> getUser() {
return userResponse;
}
public void onBtnLoginClick() {
// attemptLogin();
if (validateInputs()) {
userRepository.loginUser(username.get(), password.get());
}
}
@BindingAdapter("error")
public static void setError(EditText editText, Object strOrResId) {
if (strOrResId instanceof Integer) {
editText.setError(
editText.getContext().getString((Integer) strOrResId));
} else {
editText.setError((String) strOrResId);
}
}
@BindingAdapter("onFocus")
public static void bindFocusChange(EditText editText, View.OnFocusChangeListener onFocusChangeListener) {
if (editText.getOnFocusChangeListener() == null) {
editText.setOnFocusChangeListener(onFocusChangeListener);
}
}
//--
public boolean validateInputs() {
boolean isValid = true;
if (username.get() == null || !Validations.isUserNameValid(username.get())) {
errorUsername.set(String.valueOf(R.string.error_invalid_username));
isValid = false;
} else {
errorUsername.set(null);
}
if (password.get() == null || password.get().length() < 8 && !Validations.isPasswordValid(password.get())) {
errorPassword.set(String.valueOf(R.string.error_incorrect_password));
isValid = false;
} else {
errorPassword.set(null);
}
return isValid;
}
}
我得到的错误
E/AndroidRuntime:致命异常:主进程:com。comcredit公司。ccui。cclogin,PID:19969 java。lang.RuntimeException:无法启动活动组件信息{com.comcredit.ccui.cclogin/com.comcredit.ccui.cclogin.view.LoginActivity}:java。lang.RuntimeException:无法创建com类的实例。comcredit公司。ccui。cclogin。view\u模型。android上的LoginViewModel。应用程序。ActivityThread。在android上执行LaunchActivity(ActivityThread.java:2858)。应用程序。ActivityThread。android上的handleLaunchActivity(ActivityThread.java:2933)。应用程序。ActivityThread-android上的wrap11(未知源:0)。应用程序。android上的ActivityThread$H.handleMessage(ActivityThread.java:1612)。操作系统。处理程序。android上的dispatchMessage(Handler.java:105)。操作系统。活套。android上的loop(Looper.java:164)。应用程序。ActivityThread。java上的main(ActivityThread.java:6710)。lang.reflect。方法在com上调用(本机方法)。Android内部的操作系统。受精卵$MethodandArgscaler。在com上运行(zyote.java:240)。Android内部的操作系统。合子岩。main(ZygoteInit.java:770)由:java引起。lang.RuntimeException:无法创建com类的实例。comcredit公司。ccui。cclogin。view\u模型。android上的LoginViewModel。拱生命周期。ViewModelProvider$NewInstanceFactory。在android上创建(ViewModelProvider.java:153)。拱生命周期。ViewModelProvider$AndroidViewModelFactory。在android上创建(ViewModelProvider.java:210)。拱生命周期。ViewModelProvider。在android上获取(ViewModelProvider.java:134)。拱生命周期。ViewModelProvider。在com上获取(ViewModelProvider.java:102)。康信。ccui。cclogin。看法后勤活动。android上的onCreate(LoginActivity.java:45)。应用程序。活动在android上执行创建(Activity.java:6980)。应用程序。仪器仪表。android上的callActivityOnCreate(Instrumentation.java:1214)。应用程序。ActivityThread。在android上执行LaunchActivity(ActivityThread.java:2811)。应用程序。ActivityThread。handleLaunchActivity(ActivityThread.java:2933)
使用此代码:
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
Intent intent = new Intent(SplashActivity.this,
LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
SplashActivity.this.finish();
}
},3500);
替换代码:
splashTread = new Thread() {
@Override
public void run() {
try {
int waited = 0;
// Splash screen pause time
while (waited < 3500) {
sleep(100);
waited += 100;
}
Intent intent = new Intent(SplashActivity.this,
LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
SplashActivity.this.finish();
} catch (InterruptedException e) {
// do nothing
} finally {
SplashActivity.this.finish();
}
}
};
splashTread.start();
意图声明中的此指的是视图模型。请尝试传递完整的活动名称。
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
启动屏幕是一个用户对你应用的第一体验。 启动页面类型 占位 UI 品牌启动页面 启动页面类型 启动页面是用户对你应用的第一体验。 启动应用时,如果显示一个空白面板,会增加用户观察到的加载时间,考虑使用占位符 UI 或者一个品牌加载页面。 占位 UI 是最无缝的加载转换——适用于应用加载和应用内活动切换两者。 品牌启动页面提供了短暂的品牌曝光,让 UI 聚焦于内容上面。 品牌启动页面 占位 UI 占
问题内容: 我想构建一个锁屏更换应用程序。有什么方法可以创建一个侦听器/服务,该监听器/服务将在用户唤醒/解锁屏幕时启动我的应用程序? 问题答案: 请参阅mylockforandroid的源代码, 您将需要使用DeviceAdminReceiver来禁用默认的Android 屏幕锁。 当用户解锁屏幕将and 注册为时启动活动: 将此代码添加到manifast.xml中,将ScreenReceive
我使用一个空活动为我的应用程序创建了一个启动屏幕,该活动在背景图像中保持可见3秒钟。通常,应用程序在背景图像变为可见之前以白色屏幕启动,然而,有些应用程序已经以“真实”的初始屏幕图像启动。如何实现这一点?
我已经本地化了,通过它将LaunchScreen分成两部分。
即使屏幕被锁定,如何在设备上开始活动。我尝试了下面的方法,但是不起作用。 广播接收器:
我只是在android的mipmap文件夹和IOS的Assets.xcAssets文件夹中为我的应用图标添加了一个徽标,在drawable文件夹中使用了不同的图像,这样我就可以作为启动屏幕显示,而不是像素图标徽标。然而,现在应用程序图标显示的是闪屏图像和标识,我设计的是不显示。你知道哪个文件夹代表闪屏,哪个文件夹代表Android中的徽标吗?