【发布时间】:2014-12-09 11:42:25
【问题描述】:
我有一个片段,其中包含一个带有适配器的 ListView。我希望在替换此片段时列表视图继续在后台更改。为此,我在 AsyncTask 中创建了一个带有 TimerTask 的方法,因为我希望 ListView 每 10 秒更改一次。如果包含 ListView 的 Fragment 在不替换的情况下可见,则其工作正常,但如果我进行替换则不起作用并引发异常 NullPointerException。
我该如何解决?
我正在尝试这个。
片段
public class JogosAbertosFrag extends Fragment implements View.OnClickListener, AdapterView.OnItemClickListener {
private ImageButton btPerfil;
private Intent intentPerfil;
private ListView lvJogosFinalizados;
private ListView lvJogosAndamento;
protected ProgressDialog progressDialog;
private JogosListAdapter jogosListAdapterAndamento, jogosListAdapterFechado;
private TextView tvPontuacao;
private List<Batalha> listBatalhaAberto, listBatalhaFechado;
//clock
private Timer timer;
private TimerTask timerTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((CustomDrawerLayout)getActivity()).getSupportActionBar().show();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.jogosabertos, container, false);
lvJogosFinalizados = (ListView)rootView.findViewById(R.id.lvJogosFinalizados);
lvJogosFinalizados.setOnItemClickListener(this);
lvJogosAndamento = (ListView)rootView.findViewById(R.id.lvJogosAndamento);
lvJogosAndamento.setOnItemClickListener(this);
tvPontuacao = (TextView)rootView.findViewById(R.id.tvPontuacao);
tvPontuacao.setText(BatalhaConfigs.USUARIO_PONTUACAO);
btPerfil = (ImageButton)rootView.findViewById(R.id.btPerfil);
btPerfil.setOnClickListener(this);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
clockTask();
}
/** */
private void getAllBattles(){
ApplicationController app = new BatalhaDAO().getAllBattles(new BatalhaAdapter(){
@Override
public void getAllBattlesOpened(List<Batalha> list) {
if(!list.isEmpty()){
listBatalhaAberto = list;
if(jogosListAdapterAndamento == null){
jogosListAdapterAndamento = new JogosListAdapter(getView().getContext(), listBatalhaAberto);
lvJogosAndamento.setAdapter(jogosListAdapterAndamento);
}else{
jogosListAdapterAndamento.changeList(listBatalhaAberto);
}
}
}
@Override
public void getAllBattlesClosed(List<Batalha> list) {
if(!list.isEmpty()){
listBatalhaFechado = list;
if(jogosListAdapterFechado == null){
jogosListAdapterFechado = new JogosListAdapter(getView().getContext(), listBatalhaFechado);
lvJogosFinalizados.setAdapter(jogosListAdapterFechado);
}else{
jogosListAdapterFechado.changeList(listBatalhaFechado);
}
}
}
});
CustomVolleySingleton.getInstance(getView().getContext()).addToRequestQueue(app);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
FragmentTransaction ft;
Fragment frag;
if(parent == lvJogosAndamento){
Batalha batalha = listBatalhaAberto.get(position);
Bundle params = new Bundle();
params.putSerializable("infoBatalha", batalha);
frag = new JogarComOponenteFrag();
frag.setArguments(params);
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fl, frag);
ft.addToBackStack("back");
ft.commit();
}else if(parent == lvJogosFinalizados){
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
/** timer para atualizar o adapter */
private void clockTask(){
new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
tvPontuacao.setText(BatalhaConfigs.USUARIO_PONTUACAO);
getAllBattles();
}
});
}
};
timer.scheduleAtFixedRate(timerTask, 100, 10000);
return "execute";
}
}.execute("execute");
}
@Override
public void onStop() {
super.onStop();
CustomVolleySingleton.getInstance(getView().getContext()).cancelPendingRequests(CustomVolleySingleton.TAG);
}
}
列表适配器
public class JogosListAdapter extends BaseAdapter {
private List<Batalha> lista;
private Context context;
public JogosListAdapter(Context context, List<Batalha> list){
this.context = context;
this.lista = list;
}
@Override
public int getCount() {
return lista.size();
}
@Override
public Object getItem(int position) {
return lista.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public void changeList(List<Batalha> lista){
this.lista = lista;
notifyDataSetChanged();
}
@Override
public View getView(int position, View view, ViewGroup parent) {
View layout;
if (view == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layout = inflater.inflate(R.layout.jogos_list_adapter, parent, false);
}else{
layout = view;
}
return layout;
}
例外
FATAL EXCEPTION: main
java.lang.NullPointerException
at br.com.mypackage.myapp.frags.JogosAbertosFrag.getAllBattles(JogosAbertosFrag.java:113)
at br.com.mypackage.myapp.frags.JogosAbertosFrag.access$12(JogosAbertosFrag.java:84)
at br.com.mypackage.myapp.frags.JogosAbertosFrag$2$1$1.run(JogosAbertosFrag.java:170)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
异常行
113 has -> CustomVolleySingleton.getInstance(getView().getContext()).addToRequestQueue(app);
84 has -> private void getAllBattles(){}
170 close -> private void clockTask(){
【问题讨论】:
-
替换fragment时,所有视图都会被销毁……所以listview会为空
-
@Suvtruf 有什么办法吗?
-
不知道为什么要这么做。例如,如果将其设为静态,您可以在后台更新 List 而不是 ListView。
-
所以,如果我在
onStop()中没有解决方案,我添加了timer.cancel(); timer.purge();,现在可以工作了。非常感谢!
标签: android android-fragments android-listview android-asynctask timertask