代码之家  ›  专栏  ›  技术社区  ›  SuperDave

27.1.x中的ViewModel功能因子活动的配置更改而中断

  •  0
  • SuperDave  · 技术社区  · 6 年前

    我遇到了这种奇怪的行为,我想这可能会引起社区的兴趣。如果为父活动定义了ViewModel,则启动子活动,执行方向更改(我使用的是配置为API=24的模拟器)并返回父活动,父活动的ViewModel将被销毁,ViewModelProviders.of方法将为您分配一个全新的ViewModel。这显然不是应该发生的。我可能会误解这个功能吗?

    下面是重新创建问题的示例代码。主活动显示指向ViewModel的指针。按按钮启动子活动,然后更改方向,然后按“上一步”返回父活动。它将更新ViewModel指针。另一方面,如果从父活动执行方向更改,则不会销毁ViewModel。类似地,如果对子活动执行方向更改,然后执行另一个操作以撤消该操作,则父活动将保留原始视图模型。想想看。

    main活动.java

    package com.google.example.viewmodeltest;
    
    import android.arch.lifecycle.ViewModelProviders;
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.design.widget.FloatingActionButton;
    import android.support.design.widget.Snackbar;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.View;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.TextView;
    
    import org.w3c.dom.Text;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            MyViewModel viewModel=ViewModelProviders.of(this).get(MyViewModel.class);
            ((TextView) findViewById(R.id.infoText)).setText("ViewModel="+viewModel);
    
            findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    startActivity(new Intent(MainActivity.this,ChildActivity.class));
                }
            });
        }
    }
    

    ChildActivity.java

    package com.google.example.viewmodeltest;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    
    public class ChildActivity extends AppCompatActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_child);
        }
    }
    

    MyViewModel.java

    package com.google.example.viewmodeltest;
    
    import android.arch.lifecycle.ViewModel;
    
    public class MyViewModel extends ViewModel {
        public MyViewModel() {
            super();
        }
    }
    

    布局/活动主要.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="5dp">
    
        <TextView android:id="@+id/infoText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Press"/>
    </LinearLayout>
    

    布局/活动\子.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="This is the child activity"/>
    
    </LinearLayout>
    

    模块build.gradle

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 27
        defaultConfig {
            applicationId "com.google.example.viewmodeltest"
            minSdkVersion 14
            targetSdkVersion 27
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
    //  def supportlib_version = "28.0.0-rc01"
        def supportlib_version = "27.1.1"
    
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation "com.android.support:appcompat-v7:$supportlib_version"
        implementation "com.android.support:design:$supportlib_version"
        implementation "com.android.support.constraint:constraint-layout:1.1.2"
        implementation "android.arch.lifecycle:extensions:1.1.1"
        annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
    
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    }
    

    AndroidManifest.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.google.example.viewmodeltest">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity
                android:name=".MainActivity"
                android:label="@string/app_name"
                android:theme="@style/AppTheme.NoActionBar">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".ChildActivity" />
        </application>
    
    </manifest>
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   SuperDave    6 年前

    玩了很多次之后,我确定这个“特征”存在于支持库的版本27.1。x上,而不是在27。x上,也不是22.0.0。希望这次能修好。