如何 运行 在 Android 中每 60 秒编码一次

How to run code every 60sec in Android

在我的应用程序中,我想要 运行 每 60 秒 代码 ,这是我从服务器获取数据的代码。
为此,我写了下面的代码。
但是 60 秒后 当 运行 代码时,显示 ForceClose 错误并在 logCat.[=30= 中显示以下消息]

显示我对片段的看法的错误!

我的代码:

public class MainReminderFragment extends Fragment {

    @BindView(R.id.mainExplore_noExploreTxt)
    TextView mainExplore_noExploreTxt;
    @BindView(R.id.newsPageLoadLay)
    RelativeLayout newsPageLoadLay;
    @BindView(R.id.toolbarTitleTxt)
    TextView toolbarTitleTxt;
    private Context context;
    public List<Datum> model = new ArrayList<>();
    public ReminderAdapter reminderAdapter;
    private SharedPrefrencesHandler prefrencesHandler;
    private String token = "";
    private LinearLayoutManager layoutManager;
    private MainActivity mainActivity;
    private InterfaceApi api;
    private boolean isRunning = false;
    public ProgressBar mainExplore_progressBar;
    public RecyclerView mainExplore_recyclerView;

    public MainReminderFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_main_reminder, container, false);
        //Initialize
        ButterKnife.bind(this, view);
        context = getActivity();
        prefrencesHandler = new SharedPrefrencesHandler(context);
        reminderAdapter = new ReminderAdapter(context, model);
        layoutManager = new LinearLayoutManager(context);
        mainExplore_progressBar = view.findViewById(R.id.mainExplore_progressBar);
        mainExplore_recyclerView = view.findViewById(R.id.mainExplore_recyclerView);
        isRunning = true;
        mainActivity = (MainActivity) getActivity();
        api = ApiClient.getClient().create(InterfaceApi.class);
        //Toolbar name
        toolbarTitleTxt.setText(context.getResources().getString(R.string.reminder));
        //RecyclerView
        mainExplore_recyclerView.setLayoutManager(layoutManager);
        mainExplore_recyclerView.setHasFixedSize(true);
        //Get token
        token = prefrencesHandler.getFromShared(SharedPrefrencesKeys.TOKEN.name());

        //Get data
        getData();
        if (getActivity() != null) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            while (true) {
                                try {
                                    Thread.sleep(60000);
                                } catch (Exception e) {
                                }
                                if (isRunning) {
                                    getData();
                                }
                            }
                        }
                    }).start();
                }
            });
        }
        return view;
    }

    //SendData method
    private SerialReminderListSendData sendData(int page) {
        SerialReminderListSendData listSendData = new SerialReminderListSendData();
        listSendData.setPageIndex(page);
        listSendData.setPageSize(200);

        return listSendData;
    }

    //Get data
    private void getData() {
        Call<SerialReminderListResponse> call = api.getListSerialReminder(token, "2", sendData(1));

        mainExplore_progressBar.setVisibility(View.VISIBLE);

        call.enqueue(new Callback<SerialReminderListResponse>() {
            @Override
            public void onResponse(Call<SerialReminderListResponse> call, Response<SerialReminderListResponse> response) {
                if (response.body().getData() != null && response.body().getStatusCode() != 401
                        && response.body().getStatusCode() != 402) {
                    if (response.body().getData().size() > 0) {
                        model.clear();
                        model.addAll(response.body().getData());
                        reminderAdapter.notifyDataSetChanged();
                        mainExplore_recyclerView.setAdapter(reminderAdapter);
                        //Gone no explore
                        mainExplore_noExploreTxt.setVisibility(View.GONE);
                    } else {
                        mainExplore_noExploreTxt.setVisibility(View.VISIBLE);
                        mainExplore_recyclerView.setVisibility(View.GONE);
                    }
                }

                mainExplore_progressBar.setVisibility(View.GONE);
            }

            @Override
            public void onFailure(Call<SerialReminderListResponse> call, Throwable t) {
                mainExplore_progressBar.setVisibility(View.GONE);
            }
        });
    }
}

logCat 中的错误消息:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7130)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1115)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5284)
at android.view.View.invalidateInternal(View.java:13615)
at android.view.View.invalidate(View.java:13579)
at android.view.View.setFlags(View.java:11422)
at android.view.View.setVisibility(View.java:8014)
at com.app.test.Fragments.MainPageFrags.MainReminderFragment.getData(MainReminderFragment.java:182)
at com.app.test.Fragments.MainPageFrags.MainReminderFragment.access0(MainReminderFragment.java:47)
at com.app.test.Fragments.MainPageFrags.MainReminderFragment.run(MainReminderFragment.java:142)
at java.lang.Thread.run(Thread.java:761)

我该如何解决?请帮助我

问题出在这里:

 getData();
    if (getActivity() != null) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                new Thread(new Runnable() { // <-- here
                    @Override
                    public void run() {
                        while (true) {
                            try {
                                Thread.sleep(60000);
                            } catch (Exception e) {
                            }
                            if (isRunning) {
                                getData();
                            }
                        }
                    }
                }).start();
            }
        });
    }

即使您对第一个线程使用 runOnUiThread,但您在其中创建了另一个线程,并且这个新线程无法访问视图。

但是我应该说我觉得你的做法很糟糕。您可以像这样轻松地使用 Timer 作为您的代码:

new Timer(new TimerTask() {
    @Override
    public void run() {
        getDate();
    }
}, 0, 60000).start();

并更改:

mainExplore_progressBar.setVisibility(View.GONE);

mainExplore_progressBar.post(new Runnable() {
    @Override
    public void run() {
        mainExplore_progressBar.setVisibility(View.GONE);
    }
}

更新: 你可以使用:

new Timer(new TimerTask() {
    @Override
    public void run() {
        getActivity().runOnUiThread(new Runnable() {
                        public void run() {
                            getData();
                        }
                    });
    }
}, 0, 60000).start();

也保持 getData() 方法不变。

每次您尝试更改 View 的属性时,您只能从最初创建它的 Thread 执行此操作。那就是主线程 / UI 线程。例如,如果您调用

mainExplore_noExploreTxt.setVisibility(View.GONE);

你必须从主线程调用它。有一个实用方法 runOnUiThread

runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mainExplore_noExploreTxt.setVisibility(View.GONE);
        }
    });

此外,您不想使用 Thread.sleep 或类似的东西。有很多 android 特定的解决方案。在这种情况下,您可能希望使用 HandlerpostDelayed.

试试这个代码:

if (getActivity() != null) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            float i;
            try {
                for (i = 0; i <= 100; i++) {
                    getActivity().runOnUiThread(new Runnable() {
                        public void run() {
                            getData();
                        }
                    });
                    sleep(6000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    thread.start();
}