当前位置: 首页 > 知识库问答 >
问题:

android中的ViewModel和可变实时数据不能正常工作

陆飞捷
2023-03-14
public class EarthquakeActivity extends AppCompatActivity {

    private static final String LOG_TAG = "MainActivity";
    private MyModel mMyModel;
    private ViewModelProvider mViewModelProvider;
    private RecyclerView mRecyclerView;
    private TextView mEmptyView;
    private EarthquakeAdapter mEarthquakeAdapter;
    private ProgressBar mProgressBar;
    private ConnectivityManager mConnectivityManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.earthquake_activity);
        mEmptyView = findViewById(R.id.empty_view);
        // get the progress bar to indicate loading
        mProgressBar = findViewById(R.id.loading_bar);
        // set a view model provider for the current activity
        mViewModelProvider = new ViewModelProvider(this);
        // get the view model for the class
        mMyModel = mViewModelProvider.get(MyModel.class);
        // find a reference to the {@link RecyclerView} in the layout
        mRecyclerView = findViewById(R.id.earthquakes);
        mConnectivityManager = getSystemService(ConnectivityManager.class);
        mEmptyView.setText("No internet available");
        mEmptyView.setVisibility(View.VISIBLE);
        Handler handler = new Handler(Looper.getMainLooper());
        mConnectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback(){
            @Override
            public void onAvailable(Network network) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        mEmptyView.setVisibility(View.GONE);
                        mProgressBar.setVisibility(View.VISIBLE);
                        fetchData();
                    }
                });
            }
        });
        Log.e(LOG_TAG,"Visibility changed");
    }

    private void fetchData(){
        // fetch the list of earthquakes
        mMyModel.getEarthquakes().observe(EarthquakeActivity.this, new Observer<ArrayList<Earthquake>>() {
            @Override
            public void onChanged(ArrayList<Earthquake> earthquakes) {
                Log.v(LOG_TAG,"fetching the data");
                // set up recycler view with this data, this will work even if you rotate the device
                setUpRecyclerView(earthquakes);
            }
        });
    }

    private void setUpRecyclerView(ArrayList<Earthquake> earthquakes) {
        if(earthquakes == null || earthquakes.size() == 0) {
            mRecyclerView.setVisibility(View.GONE);
            mProgressBar.setVisibility(View.GONE);
            mEmptyView.setText(R.string.no_data_available);
            mEmptyView.setVisibility(View.VISIBLE);
        }
        else {
            mRecyclerView.setVisibility(View.VISIBLE);
            mEmptyView.setVisibility(View.GONE);
            mProgressBar.setVisibility(View.GONE);
            // create adapter passing in the earthquake data
            mEarthquakeAdapter = new EarthquakeAdapter(EarthquakeActivity.this, earthquakes);
            // attach the adapter to the recyclerView to populate the items
            mRecyclerView.setAdapter(mEarthquakeAdapter);
            // set the layout manager to position the items
            mRecyclerView.setLayoutManager(new LinearLayoutManager(EarthquakeActivity.this));
            Log.e(LOG_TAG,"Recycler view about to be setup");
            // click listener for when an item is clicked
            mEarthquakeAdapter.setClickListener((view, position) -> searchWeb(earthquakes.get(position).getUrl()));
        }
    }
}
public class MyModel extends ViewModel {

    private static final String LOG_TAG = "MyModel";
    private MutableLiveData<ArrayList<Earthquake>> mMutableLiveData;

    public MutableLiveData<ArrayList<Earthquake>> getEarthquakes() {
        mMutableLiveData = new MutableLiveData<>();
        // call the API
        init();
        return mMutableLiveData;
    }

    public void init() {
        // perform the network request on separate thread
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                // create array list of earthquakes
                mMutableLiveData.postValue(QueryUtils.fetchEarthquakeData("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2021-06-01&limit=300"));
            }
        });
        executorService.shutdown();

    }


}
private static String makeHttpRequest(URL url) throws IOException {
        String jsonResponse = "";

        // if url null, return
        if(url == null) {
            return jsonResponse;
        }
        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            urlConnection= (HttpURLConnection)url.openConnection();
            urlConnection.setReadTimeout(10000/*milliseconds*/);
            urlConnection.setConnectTimeout(15000/*milliseconds*/);
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();
            // this is being logged again even after screen rotation
            Log.v(LOG_TAG,"Network request made");

            // if the request was successful(response code 200)
            //then read the input stream and parse the output
            if(urlConnection.getResponseCode() == 200) {
                inputStream = urlConnection.getInputStream();
                jsonResponse = readFromStream(inputStream);
            }
            else{
                Log.e(LOG_TAG,"Error Response code: " + urlConnection.getResponseCode());
            }
        }
        catch (IOException e) {
            Log.e(LOG_TAG,"Problem retrieving the earthquake JSON results",e);
        }
        finally {
            if(urlConnection != null) {
                urlConnection.disconnect();
            }
            if(inputStream != null) {
                inputStream.close();
            }
        }
        return jsonResponse;

请帮助我解决我的问题。这对我来说现在很困惑。

共有1个答案

鲁德佑
2023-03-14

看看这里,也许它可以帮助活动在旋转Android上重启

可能在屏幕旋转时,您再次调用onCreate,ViewModel也是如此

编辑:尝试用这种方式调用API

 public MutableLiveData<ArrayList<Earthquake>> getEarthquakes() {
        mMutableLiveData = new MutableLiveData<>();
        //call the API
        mMutableLiveData.init();

 类似资料:
  • 我试图运行一个读取环境变量的应用程序,该环境变量包含大约22K个字符的JSON。项目设置告诉我使用来正确配置它,但是当我使用windows时,这些命令不起作用。 我尝试使用GUI环境变量将文件的内容复制到变量中,但是它的输入会将值截断到一定的限制,这个限制甚至不到文件的一半。在此之后,我尝试使用Powershell和以下命令设置变量: 然后用以下命令保存结果:

  • 我需要观察Modelview中的livedata更改来更新片段(将列表添加到RecycerView中)。 该实现工作正常,但在片段之间切换时面临问题。 并试图将观察者移除为:或或或尝试在

  • 我有一个如下的路由,它将根据url中的数据显示配置文件: 我在主页上有一个表单,它由一个输入框和区域选择器组成。我将此数据发布到: 问题是,我不知道如何将表单数据(如召唤者名称和区域)转换为url格式,在该格式中,用户将与配置文件页面一起显示,url将为/{Region}/{courdername}。我应该在控制器内部使用重定向::吗?我觉得那样做很糟糕。有什么建议吗? 现在,当我发布数据时,ur

  • 我正试图在按下某个按钮时弹出一个警报对话框。我首先使用了Android Developer的示例代码而不是'这不起作用,所以我根据在这个站点上发现的情况进行了更改,但是现在我的程序在按下按钮后被迫停止。 就你的知识而言,这是在第二个不同于主要的活动中完成的。不确定这是否重要.... ‘ 碰撞日志:“03-25 19:34:24.373:E/AndroidRuntime(18828):致命异常:ma

  • 2,错误{org.apache.directory.server.LDAP.ldapserver}-ERR_171无法将LDAP服务(10,389)绑定到服务注册表。java.net.BindException:已在使用的地址 请帮忙谢谢 --------提示------------------- JAVA_HOME环境变量设置为/opt/java CARBON_HOME环境变量设置为/mnt/1

  • Android Studio是完美的工作,但当我执行jar文件 但jar文件在这种情况下无法执行,这是出了什么问题。有什么建议吗