我在ViewPager中有两个片段。这些片段具有为WS调用asyncs的计时器。我在OnResume中停止并恢复计时器,然后在OnPause中停止它。有时,在S4智能手机中,我有以下错误:
java.lang.NullPointerException
at futbol.app.fragment.FragmentUsuariosConectados$3.run(FragmentUsuariosConectados.java:220)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
这些是日志中报告的行,它们位于tvRegistrados.post中:
Line 219: BitmapDrawable bitmapDrawable = convertViewToDrawable(
Line 220: getActivity(), tvRegistrados);
这是我的整个片段类
public class FragmentUsuariosConectados extends Fragment {
private View view = null;
private FragmentActivity activity;
private JSONObject obj;
private Boolean isTimeToPrint;
private Boolean isWsFinished;
private UsuariosConectadosList usuariosList;
private final static int DELAY_TIME = 540000;
private Timer timer;
public FragmentUsuariosConectados newInstance() {
FragmentUsuariosConectados f = new FragmentUsuariosConectados();
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isTimeToPrint = false;
timer = new Timer();
isWsFinished = false;
getFragmentActivity();
}
@Override
public void onPause() {
stopTimer();
super.onPause();
}
@Override
public void onResume() {
resumeTimer();
super.onResume();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_usuarios_conectados,
container, false);
// Realiza una espera, para que al menu lateral le de tiempo de cerrarse
// antes de pintar la pantalla
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
isTimeToPrint = true;
if (isWsFinished && isTimeToPrint) {
onDrawScreen();
Log.e("DELAY", "ENTRA");
}
}
}, Constantes.TIME_DELAY);
return view;
}
public class WSGet extends AsyncTask<String, Integer, Void> {
// URL del ws
private String url;
private WSController ws;
public WSGet(String url) {
this.url = url;
this.ws = new WSController();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected Void doInBackground(String... params) {
Log.i("WSGET", "Chat");
obj = ws.getWS(getActivity(), url);
Gson gson = new Gson();
if (obj != null)
usuariosList = gson.fromJson(obj.toString(),
UsuariosConectadosList.class);
return null;
}
protected void onPostExecute(Void result) {
isWsFinished = true;
if (isWsFinished && isTimeToPrint) {
onDrawScreen();
}
}
}
private void onDrawScreen() {
try {
if (getFragmentActivity() != null && view != null) {
TextView tvCompartir = (TextView) view
.findViewById(R.id.tv_invitar);
tvCompartir.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new CompartirDialog(getActivity()).show();
}
});
if (usuariosList != null && usuariosList.getError() != null
&& usuariosList.getError().getCodError().equals(0)) {
loadUsuarios();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void loadUsuarios() {
UsuariosConectados usuariosConectados = usuariosList.getRespuesta();
final List<Usuario> registradosList = usuariosConectados.getUsuarios();
if (registradosList != null) {
TextView tvNumConectados = (TextView) view
.findViewById(R.id.tv_num_conectados);
tvNumConectados.setText(registradosList.size() + "");
final TextView tvRegistrados = (TextView) view
.findViewById(R.id.usuarios_registrados);
if (!registradosList.isEmpty())
tvRegistrados.setVisibility(View.VISIBLE);
final List<BitmapDrawable> bitmapList = new ArrayList<BitmapDrawable>();
tvRegistrados.post(new Runnable() {
@SuppressWarnings("deprecation")
public void run() {
for (int i = 0; i < registradosList.size(); i++) {
String nick = registradosList.get(i).getNick();
tvRegistrados.setText(nick);
tvRegistrados
.setBackgroundDrawable(getFragmentActivity()
.getResources()
.getDrawable(
R.drawable.shape_bg_usuario_registrado));
try {
BitmapDrawable bitmapDrawable = convertViewToDrawable(
getFragmentActivity(), tvRegistrados);
bitmapList.add(bitmapDrawable);
} catch (Exception e) {
e.printStackTrace();
}
}
SpannableStringBuilder sStringBuilder = new SpannableStringBuilder();
for (int i = 0; i < bitmapList.size(); i++) {
Spannable wordSpan = new SpannableString("1" + " ");
BitmapDrawable bd = bitmapList.get(i);
bd.setBounds(0, 0, (int) (bd.getIntrinsicWidth()),
(int) (bd.getIntrinsicHeight()));
wordSpan.setSpan(new ImageSpan(bd), 0, 1,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
sStringBuilder.append(wordSpan);
}
tvRegistrados.setText(sStringBuilder);
tvRegistrados.setBackgroundColor(getFragmentActivity()
.getResources().getColor(
android.R.color.transparent));
}
});
}
Integer numInvitados = 0;
if (usuariosConectados.getNumInvitados() != null) {
numInvitados = usuariosConectados.getNumInvitados();
}
TextView tvInvitados = (TextView) view
.findViewById(R.id.tv_usuarios_invitados);
tvInvitados.setText(numInvitados.toString());
}
public class WSTimerTask extends TimerTask {
@Override
public void run() {
Log.i("TIMER WS", "EXECUTE");
if (getFragmentActivity() != null) {
// Login periodico del usuario en el chat
Usuario usuario = UtilPreferencias
.getUsuario(getFragmentActivity());
if (usuario != null) {
Usuario registrado = new Usuario();
registrado.setNick(usuario.getNick());
registrado.setPassword(usuario.getPassword());
new WSLogin(registrado).execute();
} else {
Usuario invitado = new Usuario();
String uuid = UtilPreferencias
.getUuid(getFragmentActivity());
invitado.setUuid(uuid);
new WSLogin(invitado).execute();
}
// Obtiene los conectados
new WSGet(Webservices.URL_BASE
+ Webservices.USUARIOS_CONECTADOS
+ futbol.app.constante.Stylo.ID_EQUIPO).execute();
}
}
}
public class WSLogin extends AsyncTask<String, Integer, Void> {
// URL del ws
private String url;
private WSController ws;
private Usuario usuario;
public WSLogin(Usuario usuario) {
this.ws = new WSController();
if (usuario.getNick() != null && !usuario.getNick().equals(""))
this.url = Webservices.URL_BASE + Webservices.USUARIO_LOGIN;
else
this.url = Webservices.URL_BASE + Webservices.USUARIO_INVITADO;
this.usuario = usuario;
this.usuario.setIdEquipo(futbol.app.constante.Stylo.ID_EQUIPO);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected Void doInBackground(String... params) {
Log.i("WSLOGIN", "Login");
obj = ws.postWS(getFragmentActivity(), url, usuario);
return null;
}
protected void onPostExecute(Void result) {
}
}
public static BitmapDrawable convertViewToDrawable(Context context,
View view) {
int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
view.measure(spec, spec);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.translate(-view.getScrollX(), -view.getScrollY());
view.draw(c);
view.setDrawingCacheEnabled(true);
Bitmap cacheBmp = view.getDrawingCache();
Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true);
view.destroyDrawingCache();
return new BitmapDrawable(context.getResources(), viewBmp);
}
public FragmentActivity getFragmentActivity() {
if (activity == null) {
activity = this.getActivity();
}
return activity;
}
@Override
public void onDestroyView() {
stopTimer();
super.onDestroyView();
}
@Override
public void onDestroy() {
stopTimer();
super.onDestroy();
}
public Timer getTimer() {
return timer;
}
public void stopTimer() {
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
}
public void resumeTimer() {
stopTimer();
if (timer == null) {
timer = new Timer();
// Hace autologin cada 9 min.
timer.scheduleAtFixedRate(new WSTimerTask(), 0, DELAY_TIME);
}
}
}
答案 0 :(得分:0)
你有竞争条件。
您的片段已经与其父Activity分离(可能因为用户已离开它?),而AsyncTask仍在运行。
你应该在继续之前检查(getActivity()== null)来防范这种情况。