我遇到的问题是我创建了一个简单的倒计时器,使用AsyncTasks
并使用SetRetainInstance(true)
确保即使更改了ui
上的计数器更新
问题是我有一个editText
给我定时器的值,然后应该将它们传递给任务倒计时。我必须在某处遗漏某些东西,因为我似乎无法获得新的价值。
这是我用作片段的代码:
package com.example.app;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.util.Log;
public class TaskFragment extends Fragment {
private static final String TAG = TaskFragment.class.getSimpleName();
String i;
int counter;
Bundle bundle;
static interface TaskCallbacks {
public void onPreExecute();
public void onProgressUpdate(int timer);
public void onCancelled();
public void onPostExecute();
}
private TaskCallbacks mCallbacks;
private DummyTask mTask;
private boolean mRunning;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof TaskCallbacks)) {
throw new IllegalStateException("Activity must implement the TaskCallbacks interface.");
}
mCallbacks = (TaskCallbacks) activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
bundle=getArguments();
i = bundle.getString("SecValue");
Log.i("VertygoEclypse - TaskFragment-onCreate", i);
counter=Integer.parseInt(i);
}
@Override
public void onDestroy() {
super.onDestroy();
cancel();
}
public void start() {
if (!mRunning) {
bundle=getArguments();
i=bundle.getString("SecValue");
mTask = new DummyTask();
Log.i("VertygoEclypse - TaskFragment - start", i);
mTask.execute();
mRunning = true;
} else{
mTask.cancel(true);
}
}
public void cancel() {
if (mRunning) {
mTask.cancel(true);
mTask = null;
mRunning = false;
}
}
public boolean isRunning() {
return mRunning;
}
private class DummyTask extends AsyncTask<Void, Integer, Void> {
@Override
protected void onPreExecute() {
mCallbacks.onPreExecute();
mRunning = true;
counter=Integer.parseInt(i);
Log.i("Vertygo Eclypse - AsyncTask - onPreExecute", i);
}
@Override
protected Void doInBackground(Void... ignore) {
do {
publishProgress(counter);
SystemClock.sleep(1000);
counter=counter-1;
if(isCancelled()){
mTask.cancel(true);
break;
}
} while (counter>0);
return null;
}
@Override
protected void onProgressUpdate(Integer... timer) {
mCallbacks.onProgressUpdate(timer[0]);
}
@Override
protected void onCancelled() {
mCallbacks.onCancelled();
mRunning = false;
}
@Override
protected void onPostExecute(Void ignore) {
mCallbacks.onPostExecute();
mRunning = false;
}
}
}
据说我Log.i
在onCreate
,开始,预执行和后执行等多个位置设置了 01-17 17:37:12.383 10261-10261/com.example.app I/VertygoEclypse - replaceFrag﹕ 35
01-17 17:37:12.383 10261-10261/com.example.app I/VertygoEclypse - replaceFrag﹕ 35
01-17 17:37:12.383 10261-10261/com.example.app I/Vertygo Eclypse - MainActivity - replaceFrag﹕ 35
01-17 17:37:12.403 10261-10261/com.example.app I/VertygoEclypse - TaskFragment-onCreate﹕ 35
01-17 17:37:17.247 10261-10261/com.example.app I/VertygoEclypse - TaskFragment - start﹕ 15
01-17 17:37:17.259 10261-10261/com.example.app I/Vertygo Eclypse - AsyncTask - onPreExecute﹕ 15
。
以下来自logcat的摘录显示,某些值显示输入的文本,但start和preexecute保留旧值:
package com.example.app;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.concurrent.TimeUnit;
public class MainActivity extends FragmentActivity implements TaskFragment.TaskCallbacks {
private static final String TAG = MainActivity.class.getSimpleName();
private static final String KEY_CURRENT_PROGRESS = "current_progress";
private static final String KEY_PERCENT_PROGRESS = "percent_progress";
private static final String TIME_COUNT = "time_count";
private TaskFragment mTaskFragment;
private ProgressBar mProgressBar;
private TextView mPercent, tv1;
private Button mButton;
private EditText secentered;
public String sample;
Bundle bundl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.textView1);
secentered = (EditText) findViewById(R.id.valueentered);
mButton = (Button) findViewById(R.id.task_button);
initialfrag();
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mTaskFragment.isRunning()) {
mButton.setText("Start");
mTaskFragment.cancel();
replaceFrag();
} else {
mButton.setText("Cancel");
mTaskFragment.start();
}
}
});
if (savedInstanceState != null) {
tv1.setText(savedInstanceState.getString(TIME_COUNT));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(TIME_COUNT, tv1.getText().toString());
}
@Override
public void onPreExecute() {
mButton.setText(getString(R.string.cancel));
Toast.makeText(this, R.string.task_started_msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onProgressUpdate(int timer) {
long timelong = timer*1000;
String tval = getDurationBreakdown(timelong);
tv1.setText(tval);
}
@Override
public void onCancelled() {
mButton.setText(getString(R.string.start));
tv1.setText("0 seconds");
mTaskFragment.cancel();
replaceFrag();
Toast.makeText(this, R.string.task_cancelled_msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onPostExecute() {
mButton.setText(getString(R.string.start));
tv1.setText("Completed");
mTaskFragment.cancel();
replaceFrag();
Toast.makeText(this, R.string.task_complete_msg, Toast.LENGTH_SHORT).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_trigger_config_change:
recreate();
return true;
}
return super.onOptionsItemSelected(item);
}
public static String getDurationBreakdown(long secondstobreak) {
if(secondstobreak < 0)
{
throw new IllegalArgumentException("Duration must be greater than zero!");
}
long hours = TimeUnit.MILLISECONDS.toHours(secondstobreak);
secondstobreak-=TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(secondstobreak);
secondstobreak-=TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(secondstobreak);
secondstobreak-=TimeUnit.SECONDS.toMillis(seconds);
StringBuilder sb = new StringBuilder(64);
if(hours<10){
sb.append("0"+hours);
}else {
sb.append(hours);
}
sb.append(" : ");
if(minutes<10){
sb.append("0"+minutes);
}else{
sb.append(minutes);
}
sb.append(" : ");
if(seconds<10){
sb.append("0"+seconds);
} else {
sb.append(seconds);
}
sb.append(" remaining");
return (sb.toString());
}
public void replaceFrag(){
Bundle bundle = new Bundle();
String tester2 = secentered.getText().toString();
Log.i("VertygoEclypse - replaceFrag", tester2);
if(tester2.matches("")){
bundle.putString("SecValue", "15");
} else {
Log.i("VertygoEclypse - replaceFrag", tester2);
bundle.putString("SecValue", tester2);
}
FragmentTransaction rfm = getSupportFragmentManager().beginTransaction();
rfm.remove(mTaskFragment);
rfm.detach(mTaskFragment);
TaskFragment mTaskFragment = new TaskFragment();
Log.i("Vertygo Eclypse - MainActivity - replaceFrag", tester2);
mTaskFragment.setArguments(bundle);
rfm.add(mTaskFragment, "task").commit();
}
public void initialfrag(){
bundl = new Bundle();
String tester = secentered.getText().toString();
Log.i("VertygoEclypse - initialFrag", tester);
if(tester.matches("")){
bundl.putString("SecValue", "15");
} else{
Log.i("VertygoEclypse - initialFrag", tester);
bundl.putString("SecValue", tester);
}
FragmentManager fm = getSupportFragmentManager();
mTaskFragment = (TaskFragment) fm.findFragmentByTag("task");
if (mTaskFragment == null) {
mTaskFragment = new TaskFragment();
mTaskFragment.setArguments(bundl);
fm.beginTransaction().add(mTaskFragment, "task").commit();
}
}
}
我也使用Bundle将文本从EditText传输到片段,并使用getString()根据键获取值。
到目前为止,下面是MainActivity。
AsyncTask
我知道该值正在传递给片段,但我不确定AsyncTask
或片段是否被替换或刷新。我想要的理想情况是使用Bundle中的新值来杀死{{1}}并创建一个新的。
非常感谢任何帮助。
答案 0 :(得分:0)
好吧,我似乎偶然发现了答案。问题是int counter, validcounter;
似乎没有前面的static
,变量会创建它自己的实例。所以使用以下static int counter, validcounter;
问题就解决了。
感谢发声板。
问候
cchinchoy