[英]Update a ListView in background?
I have a Fragment that contain a ListView with Adapters. 我有一个包含带有适配器的ListView的片段。 I want when replace this Fragment the listview continue changing on background. 我想要替换此片段时,列表视图在后台继续更改。 To do it I create a method with a TimerTask inside a AsyncTask, because I want the ListView change to each 10 seconds. 为此,我创建了一个在AsyncTask内包含TimerTask的方法,因为我希望ListView每10秒更改一次。 If the Fragment that contain the ListView is visible without replace its works fine, but if I make replace isn't works and throws an exception NullPointerException. 如果包含ListView的Fragment在不进行替换的情况下可见,则可以正常工作,但是如果我进行替换,则无法正常工作,并抛出NullPointerException异常。
How can I solve it ? 我该如何解决?
I'm trying this. 我正在尝试这个。
Fragment 分段
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);
}
}
ListAdapter ListAdapter
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;
}
Exception 例外
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)
Exception Lines 例外行
113 has -> CustomVolleySingleton.getInstance(getView().getContext()).addToRequestQueue(app);
84 has -> private void getAllBattles(){}
170 close -> private void clockTask(){
First of All, you need to assign the Anonymous Inner Type AsyncTask class to a class variable. 首先,您需要将Anonymous Inner Type AsyncTask类分配给一个类变量。 Before doing that you need to create a nested AsyncTask class within your Activity. 在此之前,您需要在Activity中创建一个嵌套的AsyncTask类。
Your extended AsyncTask class should look something like this : 您扩展的AsyncTask类应如下所示:
public class MyContinousAsyncTask extends 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";
}
}
Then you need to declare a class variable of this Class in your Activity: 然后,您需要在Activity中声明此类的类变量:
private MyContinousAsyncTask myContinouslyRunningAsyncTask;
now after doing the above, just modify your clockTask()
method like this: 现在,完成上述操作后,只需像这样修改您的clockTask()
方法即可:
/** timer para atualizar o adapter */
private void clockTask(){
myContinouslyRunningAsyncTask = new MyContinousAsyncTask();
myContinouslyRunningAsyncTask.execute("execute");
}
now you should stop this AsyncTask on the onPause()
Event of your Fragment, other wise you will be getting NPE
because of accessing the de-allocated UI Components. 现在您应该在Fragment的onPause()
事件上停止此AsyncTask,否则,由于访问已取消分配的UI组件,您将获得NPE
。
The code should look like this: 该代码应如下所示:
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if(myContinouslyRunningAsyncTask != null)
{
myContinouslyRunningAsyncTask.cancel();
}
if(timer != null)
{
timer.cancel();
timer.purge();
}
}
To make your code further efficient, you should not call the clockTask();
为了使您的代码更加高效,您不应调用clockTask();
in onActivityCreated(..)
method, but in onResume()
method, like this: 在onActivityCreated(..)
方法中,但是在onResume()
方法中,如下所示:
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
clockTask();
}
I hope this helps. 我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.