我有一个很大的问题就是现在困扰我几天。在我正在开发的应用程序中,我有几个活动,其中一个是中心(BaseActivity),应用程序从中进入其他活动,并且每个活动都与Volley Library一起从API获取数据。
因此,例如,如果我从BaseActivity转到SelectionActivity,则在SelectionActivity中,我会收到包含所有必要数据的循环视图。这很好,这就是我需要的。
但是,当我通过单击工具栏上的后退按钮或主页按钮完成活动,然后想要再次返回到SelectionActivity时,数据不会再次加载。它没有说明任何异常,只是没有加载任何东西。
我一直在互联网上搜索,但我似乎无法找到解决方案。
编辑:当我使用调试器进行调查时,可以进一步确定。似乎一切都应该有效,因为它通过响应,并通过一切。但是,我没有看到任何内容,而是使用了填充数据的RecyclerView。
SelectionController方法:
public void getAllJobs()
{
queue = VolleyRequestHandler.getInstance(false).getQueue();
JsonArrayRequest jobsRequest = new JsonArrayRequest(Request.Method.GET,makeAllJobsRequest(),
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
List<Job> jobs = new ArrayList<>();
Job job;
try
{
for (int i=0; i<response.length(); i++)
{
JSONObject dbJob = response.getJSONObject(i);
job = new Job();
job.setId(dbJob.getLong("JobId"));
job.setName(dbJob.getString("JobText"));
job.setCustName(dbJob.getString("CustomerName"));
jobs.add(job);
}
// Entries are being sorted!
Collections.sort(jobs, new CustomerComparator());
injection.onGettingAllJobs(jobs);
}
catch (JSONException e)
{
e.printStackTrace();
injection.onErrorSelection(e.getMessage());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
injection.onErrorSelection(error.getMessage());
}
});
jobsRequest.setTag(injection.GET_JOBS_TAG);
jobsRequest.setRetryPolicy(new DefaultRetryPolicy(
(int) TimeUnit.SECONDS.toMillis(10),//time out in 10second
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,//DEFAULT_MAX_RETRIES = 1;
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(jobsRequest);
}
SelectionInjection接口:
public interface SelectionInjection
{
public static final String GET_JOBS_TAG = "SELECTION_GET_JOBS_TAG";
public static final String GET_TASKS_TAG = "SELECTION_GET_TASKS_TAG";
public static final String SAVE_ENTRY_TAG ="SELECTION_SAVE_ENTRY_TAG";
public void onGettingAllJobs(List<Job> jobs);
public void onGettingTasksForJob(List<Task> tasks);
public void onSavedEntry(TimeEntry savedEntry);
public void onErrorSelection(String message);
}
SelectionActivity:
public class SelectionActivity extends ActionBarActivity implements SelectionInjection {
private static final String TAG = SelectionActivity.class.getName();
/*
* Init variables for Recycler Views
* */
private LinearLayoutManager mLayoutManager;
private SelectJobAdapter mJobsAdapter;
private StickyHeadersItemDecoration headers;
private SelectTaskAdapter mSelectTaskAdapter;
/*
* Lists used for adapter and for storing information from server
* */
private List<Job> mJobs;
private List<Task> mTasks;
private SelectionController controller;
private Job selectedJob;
// Inject Views with ButterKnife
@InjectView(R.id.select_job_recyclerview) SuperRecyclerView mJobSuperRecyclerView;
@InjectView(R.id.select_task_recyclerview) SuperRecyclerView mTaskSuperRecyclerView;
@InjectView(R.id.job_view)FrameLayout mJobView;
@InjectView(R.id.task_view) FrameLayout mTaskView;
@InjectView(R.id.toolbar_actionbar) Toolbar mToolbarAction;
private int mAnimDuration;
// private SelectionTask mFetchingTask; // Is it a good idea to Init it here? -> Nej
// private SaveSelectionTask mSavingTask;
// TODO: Figure out why after coming back again to this activity, there is only a loading wheel and nothing shows up
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_selection);
ButterKnife.inject(this);
/*
* Setting up stuff for ViewSwitching
* */
mTaskView.setVisibility(View.GONE); // Also set in XMl but just in case :D
mAnimDuration = getResources()
.getInteger(android.R.integer.config_mediumAnimTime);
/*
* Setting Up Action Bar
* */
mToolbarAction.setTitle(getString(R.string.select_job_title));
setSupportActionBar(mToolbarAction);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true); // Hierarchical activity
if (mJobs == null) {
// provifing dummy test data
Log.v(TAG, "mJobs are are null");
// mJobs = new ArrayList<Job>();
// List<Task> taskList = new ArrayList<Task>();
// taskList.add(
// new Task(88,"Task Name Doh")
// );
// taskList.add(
// new Task(99,"Another Task Name Doh")
// );
// mJobs.add(
// new Job(
// 10,
// "Test Job",
// 1337,
// "Fake Customer",
// taskList
// ));
fetchJobs();
}
else
{
setUpJobRecyclerView();
}
}
private void fetchJobs() {
Log.v(TAG,"fetchJobs();");
// mFetchingTask = new SelectionTask();
// mFetchingTask.execute(); // No PAram, get all the jobs
controller = SelectionController.getInstance(BaseActivity.currentUser,this);
controller.getAllJobs();
}
private void fetchTasks(Job job){
Log.v(TAG,"fetchTAsks()");
try{
// mFetchingTask = new SelectionTask();
// mFetchingTask.execute(job);
controller = SelectionController.getInstance(BaseActivity.currentUser,this);
controller.getTasksForJob(job);
}catch (Exception e){
Log.v(TAG,"There was an error fetching tasks");
e.printStackTrace();
Toast.makeText(this,"There was error fetching tasks",Toast.LENGTH_LONG).show();
}
}
/**
* Method for setting up Job Recycler View
*/
private void setUpJobRecyclerView(){
/*
* Setting up Jobs Recycler View
* */
mJobsAdapter = new SelectJobAdapter(mJobs);
mJobsAdapter.setHasStableIds(true);
headers = new StickyHeadersBuilder()
.setAdapter(mJobsAdapter)
.setRecyclerView(mJobSuperRecyclerView.getRecyclerView())
.setStickyHeadersAdapter(new SelectJobHeaderAdapter(mJobs))
.build();
mJobSuperRecyclerView.setAdapter(mJobsAdapter);
mJobSuperRecyclerView.addItemDecoration(headers);
mLayoutManager = new LinearLayoutManager(this);
mJobSuperRecyclerView.setLayoutManager(mLayoutManager);
// Setting up onClickListener
mJobSuperRecyclerView.
addOnItemTouchListener(
new RecyclerUtils.RecyclerItemClickListener(
this,
new RecyclerUtils.RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
selectedJob = mJobs.get(position);
showMaterialDialog(position);
}
}));
}
/**
* Method used for settigng up and initalising all the adapters
* for TaskRecyclerView
* */
private void setUpTaskRecyclerView() {
mLayoutManager = new LinearLayoutManager(this);
mTaskSuperRecyclerView.setLayoutManager(mLayoutManager);
mSelectTaskAdapter = new SelectTaskAdapter(mTasks);
mSelectTaskAdapter.setHasStableIds(true);
headers = new StickyHeadersBuilder()
.setAdapter(mSelectTaskAdapter)
.setRecyclerView(mTaskSuperRecyclerView.getRecyclerView())
.setStickyHeadersAdapter(new SelectTaskHeaderAdapter(mTasks))
.build();
mTaskSuperRecyclerView.setAdapter(mSelectTaskAdapter);
mTaskSuperRecyclerView.addItemDecoration(headers);
mTaskSuperRecyclerView.
addOnItemTouchListener(
new RecyclerUtils.RecyclerItemClickListener(
this,
new RecyclerUtils.RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.v(TAG,"TaskRecyclerView onItemClick");
Toast.makeText(getApplicationContext(),"The Task has been added",Toast.LENGTH_LONG).show();
// mSavingTask = new SaveSelectionTask();
// mSavingTask.execute(mTasks.get(position));
}
}));
}
/**
* A method that starts a corssfade Animation between JobView and TaskView
*
*/
private void crossfadeViews(final View fromView, View toView){
// Set the Task view to 0% opacity but visible, so that it is visible
// (but fully transparent) during the animation.
toView.setAlpha(0f);
toView.setVisibility(View.VISIBLE);
// Animate the Task view to 100% opacity, and clear any animation
// listener set on the view.
toView.animate()
.alpha(1f)
.setDuration(mAnimDuration)
.setListener(null);
// Animate the Job view to 0% opacity. After the animation ends,
// set its visibility to GONE as an optimization step (it won't
// participate in layout passes, etc.)
fromView.animate()
.alpha(0f)
.setDuration(mAnimDuration)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
fromView.setVisibility(View.GONE);
}
});
}
/**
* Method that creates and shows a Dialog
* and executes fetchTasks() if given option is picked.
*/
private void showMaterialDialog(final int position){
// TODO: Consider starting running he Async Task straight away as
// it might be likely that the user will pick "Pcik A Task" option
// and this might speed up the process
Log.v(TAG,"showMAterialDialog");
new MaterialDialog.Builder(this)
.title("Choose Action")
.positiveText("Add Job")
.negativeText("Pick A Task")
.neutralText("CANCEL")
.callback(new MaterialDialog.ButtonCallback(){
@Override
public void onPositive(MaterialDialog dialog) {
// Add Job
Log.v(TAG,"Adding the whole Job");
// mSavingTask = new SaveSelectionTask();
// mSavingTask.execute();
controller = SelectionController.getInstance(BaseActivity.currentUser,SelectionActivity.this);
controller.saveNewTimeEntry(BaseActivity.selectedDate,selectedJob,null);
}
@Override
public void onNegative(MaterialDialog dialog) {
/**
*Pick a Task
*/
fetchTasks(mJobs.get(position));
Log.v(TAG, "Switching Views");
crossfadeViews(mJobView, mTaskView);
}
@Override
public void onNeutral(MaterialDialog dialog) {
Log.v(TAG,"Cancelling the Dialog Choice");
}
}).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.global, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
try
{
switch(id)
{
case R.id.action_settings:
return true;
case android.R.id.home:
if (mTaskView.getVisibility() == View.VISIBLE)
{
crossfadeViews(mTaskView,mJobView);
}
else
{
finish();
}
return true;
default:
throw new Exception();
}
}
catch (Exception e)
{
e.printStackTrace();
return super.onOptionsItemSelected(item);
}
}
@Override
public void onSavedEntry(TimeEntry savedEntry)
{
Log.v("SAVED ENTRY", "TRUE");
System.out.println(savedEntry.toString());
controller.closeQueue(SAVE_ENTRY_TAG);
}
@Override
public void onGettingAllJobs(List<Job> jobs) {
mJobs = jobs;
setUpJobRecyclerView();
controller.closeQueue(GET_JOBS_TAG);
}
@Override
public void onGettingTasksForJob(List<Task> tasks) {
mTasks = tasks;
setUpTaskRecyclerView();
controller.closeQueue(GET_TASKS_TAG);
}
@Override
public void onErrorSelection(String message) {
Log.v(TAG,"onErrorJobTask");
}
}
答案 0 :(得分:2)
经过大量调试后,我遇到了解决方案:
似乎我制作控制器和注入的方式并不适合Android开发,因此我已将代码重新组织回活动和片段,现在所有工作都已完成。
编辑:
最后我弄清楚了实际问题是什么。当我将Context传递给Controller时...我只在实际实例化它时才这样做。而且因为在我的情况下控制器是单例,所以在重新进入Activity时我一直在使用旧的上下文。
我无法相信我没有得到那个。 :)