Android ViewModel, обновление живых данных внутри таймера

#javascript #android #viewmodel #android-livedata

#javascript #Android #viewmodel #android-livedata

Вопрос:

Я хотел бы иметь таймер обратного отсчета в своем мобильном приложении, я использовал ViewModel и LiveData для обмена данными между различными действиями и обновления пользовательского интерфейса. Я знаю, что ViewModel и LiveData работают, так как у меня есть кнопка, которая сохраняет данные, но когда я пытаюсь сделать то же самое с таймера, я получаю следующую ошибку:

Ваша активность еще не привязана к экземпляру приложения. Вы не можете запросить ViewModel перед вызовом onCreate.

Я думаю, что «модель = новый ViewModelProvider(this).get(viewmodelclass.class );» неверно, но я попытался отложить таймер перед вызовом класса ViewModel, чтобы у него было время для инициализации всех переменных. Итак, не уверен, как получить ссылку на класс ViewModel?

Любые идеи о том, как исправить эту проблему, будут высоко оценены, поскольку это кажется очень простым, но ходить по кругу, пытаясь это исправить.

Класс MainActivity

 package com.example.viewmodellivedata_sandpit;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity
{
    private Button buttonBack_activity;

    public viewmodelclass model;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       // Get a reference to the ViewModel
       model = new ViewModelProvider(this).get(viewmodelclass.class);
       LiveData<String> shoppingList = model.getshoppinglist();

       model.getshoppinglist().observe(this, new Observer<String>(){
       @Override
       public void onChanged(@Nullable String s)
       {
            Log.d("Debug", "String has been updated");
       }
    });
    TextView textView_1 = findViewById(R.id.textView1);
    buttonBack_activity = (Button) findViewById(R.id.button1);
    buttonBack_activity.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View view) {
            Log.d("Debug", "Button pressed");
            model.writedatatest("send text");
        }


    });

    TimerStateMachineClass mActivity= new TimerStateMachineClass();
    mActivity.starttimer();

    }

}
 

Класс ViewModel

 package com.example.viewmodellivedata_sandpit;

import android.util.Log;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class viewmodelclass extends ViewModel {
public MutableLiveData<String> shoppingList;

public MutableLiveData<String> getshoppinglist() {
    if (shoppingList == null) {
        Log.w("Debug", "Inside the get shopping list");
        shoppingList = new MutableLiveData<>();
        writedatatest("test message");
    }
    return shoppingList;
  }

  public void writedatatest(String incomingdata)
  {
    Log.w("Debug", "Inside the get shopping list 1 -> " shoppingList.getValue());
    shoppingList.postValue(incomingdata);
  }

}
 

Класс таймера

 public class TimerStateMachineClass extends AppCompatActivity {

public Timer myTimer;
public viewmodelclass model;
int coutner;

public void starttimer()
{
    Log.w("Debug", "onCreate savedInstanceState");
    model = new ViewModelProvider(this).get(viewmodelclass.class);
    Log.w("Debug", "Function start timer");
    myTimer = new Timer();
    coutner = 0;
    myTimer.schedule(new TimerTask() {

        public void run() {
            TimerMethod();
        }

    }, 0, 1000);
}

  public void TimerMethod()
  {
    Log.w("Debug", "Timer execution");

   // LiveData<String> shoppingList = model.getshoppinglist();
    coutner  ;
    model.writedatatest(Integer.toString(coutner));
  }
}
 

Ответ №1:

Ответ был очень простым, просто нужно добавить onCreateView в нижней части кода

  public class MainActivity extends AppCompatActivity
 {
     private Button buttonBack_activity;
     TextView textView_1;
     public static viewmodelclass model;
     @Override
     protected void onCreate(Bundle savedInstanceState)
     {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get a reference to the ViewModel
        model = new ViewModelProvider(this).get(viewmodelclass.class);


    try{

        textView_1 = findViewById(R.id.textView1);
        buttonBack_activity = (Button) findViewById(R.id.button1);
        buttonBack_activity.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view) {
                Log.d("Debug", "Button pressed");
                model.writedatatest("send text");
            }


        });

        TimerStateMachineClass mActivity= new TimerStateMachineClass();
        mActivity.starttimer();
        LiveData<String> shoppingList = model.getshoppinglist();
        model.getshoppinglist().observe(this, new Observer<String>(){
            @Override
            public void onChanged(@Nullable String s)
            {
                textView_1.setText(s);
                Log.d("Debug", "String has been updated ->" s);
            }
        });


    }catch (Exception e)
    {
        e.printStackTrace();
    }

    }

   @Nullable
   @Override
   public View onCreateView(@NonNull String name, @NonNull Context context, 
   @NonNull AttributeSet attrs) {

        return super.onCreateView(name, context, attrs);
  }
  }