后台任务中配置更改时再次重新加载 Json 数据

Posted

技术标签:

【中文标题】后台任务中配置更改时再次重新加载 Json 数据【英文标题】:Json Data reload again on configuration changes in background tasks 【发布时间】:2021-11-18 13:00:06 【问题描述】:

我制作了一个地震报告应用程序。因为我正在通过 API 获取地震数据并将其显示在回收站视图中。 该进程通过使用Executor服务方法和runnable在后台线程上运行。 但是当我运行我的应用程序并旋转手机时,后台进程会重新执行并重新加载数据。 如何预防?我正在使用 Java 制作应用程序。

RecyclerView recyclerView;
LinearLayout nointernetLinearLayout;

ArrayList<EarthquakeModel> earthquake;
private ImageView mEmptyView;
private Button mNoInternetButton;
boolean isConnected;
private static final String url = "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2021-09-10&endtime=2021-09-11";

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


    
    recyclerView = findViewById(R.id.recycler_view);
    nointernetLinearLayout = findViewById(R.id.no_internet);
    mEmptyView = findViewById(R.id.empty_view);
    earthquake = new ArrayList<>();





    ExecutorService service = Executors.newSingleThreadExecutor();
    service.execute(new Runnable() 


        @Override
        public void run() 



      
            QueryUtils queryUtils = new QueryUtils();
            String json = queryUtils.call(url);
            try 
                ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
                isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

                if (isConnected)
                    Log.i("This is background task","it is restarted if showing again");
                    JSONObject jsonObject = new JSONObject(json);
                    JSONArray jsonArray = jsonObject.getJSONArray("features");
                    for (int i=0; i<jsonArray.length(); i++)
                        JSONObject c = jsonArray.getJSONObject(i);
                        JSONObject properties = c.getJSONObject("properties");
                        double magnitude = properties.getDouble("mag");
                        String location = properties.getString("place");
                        long time = properties.getLong("time");
                        String url = properties.getString("url");
                        EarthquakeModel earthquakeModel = new EarthquakeModel(location, magnitude,time,url);
                        earthquake.add(earthquakeModel);
                    
                

            catch (JSONException e)
                Log.e("Error","is"+e.getMessage());
            

            runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    View loadingIndicator = findViewById(R.id.loading_indicator);
                    loadingIndicator.setVisibility(View.GONE);
                    if (isConnected&&!earthquake.isEmpty())
                        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
                        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
                        recyclerView.setLayoutManager(linearLayoutManager);
                        EarthquakeAdapter earthquakeAdapter = new EarthquakeAdapter(earthquake,MainActivity.this);
                        recyclerView.setAdapter(earthquakeAdapter);
                    if(isConnected&&earthquake.isEmpty())
                        recyclerView.setVisibility(View.GONE);
                        mEmptyView.setVisibility(View.VISIBLE);
                    
                    if (!isConnected)
                        recyclerView.setVisibility(View.GONE);
                        nointernetLinearLayout.setVisibility(View.VISIBLE);
                    

                
            );



        
    );


【问题讨论】:

您的代码再次运行,因为每次方向更改都会调用 onCreate()。防止它意味着保存数据并仅在需要时获取它,或者使用 ViewModel(首选方式)。 developer.android.com/jetpack/guide 【参考方案1】:

在您的 viewModel 中运行该服务,因为 viewmodel 在配置更改后仍然存在。

使用 LiveData 更新 UI。

public ExampleViewModel extends ViewModel 
    
    private MutableLiveData<ArrayList<EarthquakeModel>> earthquake;

    public ExampleViewModel() 
        ExecutorService service = Executors.newSingleThreadExecutor();
        service.execute(new Runnable() 
            //get data
            earthquake.post(someData)
        
    
    public LiveData<ArrayList<EarthquakeModel>> getEarthQuake() 
        return earthquake;
    

然后在您的 Activity 中观察 LiveData

public class ExampleActivity extends Activity 

     private ExampleViewModel exampleViewModel;

     @Override
     protected void onCreate(Bundle savedInstanceState) 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
        exampleViewModel = new ViewModelProvider(this).get(ExampleViewModel.class);
        exampleViewModel.getEarthQuake().observe(getViewLifecycleOwner(), array -> 
          //do somthing with array
          
     

【讨论】:

以上是关于后台任务中配置更改时再次重新加载 Json 数据的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS:使用控制器和 ng-repeat 在 div 上重新加载数据

更改数据和 popViewController 后 TableView 不会重新加载

npm run watch 不会在特定更改时重新加载

停止 UITableView 在方向更改时重新加载数据

前缀更改后重新加载不和谐机器人 (Discord.py)

如何在 dotnet core 3 控制台应用程序中更改时重新加载“appsettings.json”