5

Quando provo ad ottenere un colore tramite getResources().getColor(R.color.yellow) in una normale attività ottengo questa eccezione:NullPointerException al android.content.ContextWrapper

07-12 11:58:38.019: E/AndroidRuntime(3233): FATAL EXCEPTION: main 
07-12 11:58:38.019: E/AndroidRuntime(3233): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.moveinblue.planner/com.moveinblue.planner.controller.plan.PlanDayScreen}: java.lang.NullPointerException 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1993) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2104) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.app.ActivityThread.access$600(ActivityThread.java:132) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1157) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.os.Handler.dispatchMessage(Handler.java:99) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.os.Looper.loop(Looper.java:137) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.app.ActivityThread.main(ActivityThread.java:4575) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at java.lang.reflect.Method.invokeNative(Native Method) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at java.lang.reflect.Method.invoke(Method.java:511) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at dalvik.system.NativeStart.main(Native Method) 
07-12 11:58:38.019: E/AndroidRuntime(3233): Caused by: java.lang.NullPointerException 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.content.ContextWrapper.getResources(ContextWrapper.java:81) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at com.moveinblue.planner.controller.plan.PlanDayScreen$4.<init>(PlanDayScreen.java:408) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at com.moveinblue.planner.controller.plan.PlanDayScreen.<init>(PlanDayScreen.java:406) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at java.lang.Class.newInstanceImpl(Native Method) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at java.lang.Class.newInstance(Class.java:1319) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.app.Instrumentation.newActivity(Instrumentation.java:1023) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1984) 
07-12 11:58:38.019: E/AndroidRuntime(3233):  ... 11 more 

Qualcuno mi può dare qualche senno di poi qui? Sono totalmente perso.

Codice nell'attività:

package com.moveinblue.planner.controller.plan; 

import java.text.SimpleDateFormat; 
import java.util.BitSet; 
import java.util.Calendar; 

import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.AutoCompleteTextView; 
import android.widget.ImageButton; 
import android.widget.ImageView; 
import android.widget.ListView; 
import android.widget.Toast; 

import com.moveinblue.api.Login; 
import com.moveinblue.api.Planner; 
import com.moveinblue.api.UnauthorizedException; 
import com.moveinblue.api.io.InvalidURLException; 
import com.moveinblue.api.io.OfflineException; 
import com.moveinblue.api.model.ModelObject; 
import com.moveinblue.api.model.Plan; 
import com.moveinblue.api.model.time.Day; 
import com.moveinblue.api.model.time.ScheduledThingToDo; 
import com.moveinblue.api.model.time.ScheduledTime; 
import com.moveinblue.api.model.time.ScheduledTime.TimeOfDay; 
import com.moveinblue.planner.R; 
import com.moveinblue.planner.controller.GenericPlannerScreen; 
import com.moveinblue.planner.controller.thingtodo.ThingsToDoListScreen; 
import com.moveinblue.planner.controller.user.LoginScreen; 
import com.moveinblue.planner.ui.actionbar.ActionBar; 
import com.moveinblue.planner.ui.draganddroplist.DragListener; 
import com.moveinblue.planner.ui.draganddroplist.DragNDropListView; 
import com.moveinblue.planner.ui.draganddroplist.DropListener; 
import com.moveinblue.planner.ui.draganddroplist.RemoveListener; 
import com.moveinblue.planner.utils.CommonActionStorage; 
import com.moveinblue.planner.utils.CurrentItemsStorage; 
import com.moveinblue.planner.utils.adapter.DragNDropAdapter; 
import com.moveinblue.planner.utils.adapter.listeners.OnCheckListener; 

public class PlanDayScreen extends GenericPlannerScreen { 

DragNDropListView lista; 
AutoCompleteTextView actv; 
String[] dests; 
DragNDropAdapter adapter; 
private Boolean idDroppedOrDeleted = false; 
private BitSet checkedBoxes = new BitSet(); 
private boolean firstLoad = true; 
Day day; 
@SuppressWarnings("unused") 
private static final String LOG_TAG = PlanDayScreen.class 
     .getCanonicalName(); 

@Override 
public void load() { 
    setContentView(R.layout.plan_day_list); 
    setUpList(); 
    setUpBottomLayout(false); 
    lista.requestFocus(); 
} 

@Override 
protected void loadActionBar() { 
    Plan p = CurrentItemsStorage.currentPlan; 
    Calendar c = CurrentItemsStorage.currentDay; 
    ab = new ActionBar(this, ActionBar.TYPE_LIST); 
    String date = new SimpleDateFormat("MMM dd, yyyy").format(c.getTime()); 
    date = Character.toUpperCase(date.charAt(0)) + date.substring(1); 
    date = "(" + date + ")"; 
    String title; 

    title = (p != null) ? p.name + " " + date : "Draft plan"; 

    ab.setTitle(title); 
    ab.setBackAction(R.drawable.back, new OnClickListener() { 

     @Override 
     public void onClick(View arg0) { 
      Intent intent = new Intent(PlanDayScreen.this, 
        PlanTabsScreen.class); 
      intent.putExtra("tab", 2); 
      startActivity(intent); 
      overridePendingTransition(android.R.anim.slide_in_left, 
        android.R.anim.fade_out); 

     } 
    }); 
    CommonActionStorage.setUpActionBar(ab); 
} 

private void addNewTTD() { 
    if (getIntent().getBooleanExtra("schedule", false) && firstLoad) { 
     try { 
      Calendar c = CurrentItemsStorage.currentDay; 
      TimeOfDay tod = CurrentItemsStorage.currentTimeOfDaySelectedOption; 
      Planner.schedule(
        CurrentItemsStorage.getCurrentThingToDo().ttdId, 
        new ScheduledTime(c, tod)); 
     } catch (Exception ex) { 
      ex.getStackTrace(); 
     } 
    } 
    firstLoad = false; 
} 

/** 
* Sets up a bottom bar button 
* 
* @param id 
*   The bottom bar button id you want to set 
*/ 
private void setUpBottomButton(int id) { 
    ImageButton b = (ImageButton) findViewById(id); 
    switch (id) { 
    case R.id.buttonBottom1: 
     if (!areThereCheckedBoxes()) { 
      b.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        // Add TTD to plan 
        Intent intent = new Intent(PlanDayScreen.this, 
          ThingsToDoListScreen.class); 
        startActivity(intent); 
       } 
      }); 
     } else { 
      b.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        // Date 
       } 
      }); 
     } 
     break; 
    case R.id.buttonBottom2: 
     if (!areThereCheckedBoxes()) { 
      b.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        // Map 
        if (day != null) { 
         CurrentItemsStorage.mapModelObjects = new ModelObject[0]; 
         CurrentItemsStorage.mapModelObjects[1] = day; 
         Intent intent = new Intent(PlanDayScreen.this, 
           PlanTabsScreen.class); 
         startActivity(intent); 
        } 

       } 
      }); 
     } else { 
      b.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        // Confirm 
        new AlertDialog.Builder(PlanDayScreen.this) 
          .setIcon(android.R.drawable.ic_dialog_alert) 
          .setTitle(
            "Remove " + checkedCount() 
              + " things to do") 
          .setMessage(
            "Do you really wish to remove " 
              + checkedCount() 
              + " things to do from your plan?") 
          .setPositiveButton("Yes", 
            new DialogInterface.OnClickListener() { 

             @Override 
             public void onClick(
               DialogInterface dialog, 
               int which) { 
              // Remove 
              for (int i = 0; i < lista 
                .getCount(); i++) { 
               if (checkedBoxes.get(i)) { 
                // Get checked item 
                Object ttd = adapter 
                  .getItem(i); 
                if (ttd instanceof ScheduledThingToDo) { 
                 try { 
                  // Remove it 
                  ScheduledThingToDo tTD = (ScheduledThingToDo) ttd; 
                  Planner.unschedule(
                    tTD.ttdId, 
                    tTD.time); 
                 } catch (OfflineException ex) { 
                  Toast.makeText(
                    PlanDayScreen.this, 
                    getResources() 
                      .getString(
                        R.string.unschedule_error), 
                    Toast.LENGTH_SHORT) 
                    .show(); 
                 } catch (InvalidURLException e) { 
                 } 
                } 
               } 
              } 
              // Reset checkedBoxes and 
              // BottomLayout 
              checkedBoxes = new BitSet(); 
              setUpBottomLayout(false); 
              // Redraws the list 
              setUpList(); 
             } 
            }).setNegativeButton("No", null).show(); 
       } 
      }); 
     } 
     break; 
    case R.id.buttonBottom3: 
     b.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // Update 

      } 

     }); 
     break; 
    } 
} 

/** 
* Sets up the list 
*/ 
private void setUpList() { 
    lista = (DragNDropListView) findViewById(R.id.listViewAgenda); 
    new LoadList(); 
} 

/** 
* Counts the number of checked boxes 
* 
* @return the number of checked boxes 
*/ 
private int checkedCount() { 
    int x = 0; 
    for (int i = 0; i < checkedBoxes.length(); i++) { 
     x += checkedBoxes.get(i) ? 1 : 0; 
    } 
    return x; 
} 

/** 
* Changes the buttoms on the bottom action bar. If you pass true, you get 
* the "delete items" action bar. Else, you get the "add items" action bar. 
* 
* @param isAnythingMarked 
*   True if you want to delete items, false if you want to add 
*   them. 
*/ 
private void setUpBottomLayout(boolean isAnythingMarked) { 
    ImageButton b1 = (ImageButton) findViewById(R.id.buttonBottom1); 
    ImageButton b2 = (ImageButton) findViewById(R.id.buttonBottom2); 
    ImageButton b3 = (ImageButton) findViewById(R.id.buttonBottom3); 
    b1.setImageDrawable(getResources().getDrawable(
      isAnythingMarked ? R.drawable.action_plans 
        : R.drawable.action_add)); 
    b2.setImageDrawable(getResources().getDrawable(
      isAnythingMarked ? R.drawable.action_delete 
        : R.drawable.action_map)); 
    b3.setImageDrawable(getResources() 
      .getDrawable(R.drawable.action_reload)); 
    setUpBottomButton(R.id.buttonBottom1); 
    setUpBottomButton(R.id.buttonBottom2); 
    setUpBottomButton(R.id.buttonBottom3); 
} 

private boolean areThereCheckedBoxes() { 
    for (int i = 0; i < checkedBoxes.length(); i++) { 
     if (checkedBoxes.get(i)) { 
      return true; 
     } 
    } 
    return false; 
} 

public void clickControlRowHandler(View v) { 
    Intent intent = new Intent(PlanDayScreen.this, 
      ThingsToDoListScreen.class); 
    startActivity(intent); 
} 

/** 
* Drop Listener for the DragNDropListView 
*/ 
private DropListener mDropListener = new DropListener() { 
    public void onDrop(final int from, int to) { 
     if (to == 0) 
      to = 1; 
     // If initial position is the same as final position, do nothing. 
     if (to != from) { 
      if (adapter instanceof DragNDropAdapter) { 
       if (adapter.getItem(from) instanceof ScheduledThingToDo) { 
        new DropCall(from, to); 
        ((DragNDropAdapter) adapter).onDrop(from, to); 
       } 
      } 
     } 
    } 
}; 

public OnClickListener onClickSave = new OnClickListener() { 

    public void onClick(View v) { 
     try { 
      if (Login.isRegistered()) { 
       if (Planner.loadPlan().name == null) { 
        CurrentItemsStorage.shallGoAfterCreatePlan = PlanDayScreen.class; 
        if (idDroppedOrDeleted) { 
         manageListChanges(); 
        } 
        Intent intent = new Intent(PlanDayScreen.this, 
          SavePlanScreen.class); 
        startActivity(intent); 
        return; 
       } 
      } else { 
       CurrentItemsStorage.currentPlan = Planner.loadPlan(); 
       CurrentItemsStorage.shallGoAfterLogin = PlanDayScreen.class; 
       Intent intent = new Intent(PlanDayScreen.this, 
         LoginScreen.class); 
       startActivity(intent); 
      } 

     } catch (OfflineException e) { 
      Toast.makeText(PlanDayScreen.this, 
        getResources().getString(R.string.plan_error), 
        Toast.LENGTH_SHORT).show(); 
     } 
     if (idDroppedOrDeleted) { 
      manageListChanges(); 
     } 
    } 
}; 

/** 
* Unschedules every TTD, then schedules it again. 
*/ 
private void manageListChanges() { 

    for (int i = 0; i < adapter.getCount(); i++) { 
     Object item = adapter.getItem(i); 
     if (item instanceof ScheduledThingToDo) { 
      try { 
       ScheduledThingToDo scheduled = (ScheduledThingToDo) item; 
       Planner.unschedule(scheduled.getId(), scheduled.time); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
    int state = 0; 
    for (int it = 0; it < adapter.getCount(); it++) { 
     Object item = adapter.getItem(it); 
     TimeOfDay tod = TimeOfDay.morning; 
     if (item instanceof ScheduledThingToDo) { 
      switch (state) { 
      case 1: 
       tod = TimeOfDay.morning; 
       break; 
      case 2: 
       tod = TimeOfDay.afternoon; 
       break; 
      case 3: 
       tod = TimeOfDay.evening; 
       break; 
      } 
      try { 
       Planner.schedule(((ScheduledThingToDo) item).ttdId, 
         new ScheduledTime(CurrentItemsStorage.currentDay, 
           tod)); 
      } catch (OfflineException e) { 
       Toast.makeText(PlanDayScreen.this, "No connection", 
         Toast.LENGTH_SHORT).show(); 
      } 
     } else { 
      state++; 
     } 
    } 
} 

/** 
* RemoveListener for the DragNDropListView 
*/ 
private RemoveListener mRemoveListener = new RemoveListener() { 
    public void onRemove(int which) { 
     // ListAdapter adapter = getListAdapter(); 
     if (adapter instanceof DragNDropAdapter) { 
      ((DragNDropAdapter) adapter).onRemove(which); 
      lista.invalidateViews(); 
     } 
    } 
}; 

/** 
* DragListener for the DragNDropListView 
*/ 
private DragListener mDragListener = new DragListener() { 

    int backgroundColor = getResources().getColor(R.color.yellow); 
    int defaultBackgroundColor = getResources().getColor(R.color.blue_bg); 

    public void onDrag(int x, int y, ListView listView) { 
     // TODO Auto-generated method stub 
    } 

    public void onStartDrag(View itemView) { 
     itemView.setVisibility(View.INVISIBLE); 
     itemView.setBackgroundColor(backgroundColor); 
     ImageView iv = (ImageView) itemView.findViewById(R.id.imageView1); 
     if (iv != null) 
      iv.setVisibility(View.INVISIBLE); 
    } 

    public void onStopDrag(View itemView) { 
     itemView.setVisibility(View.VISIBLE); 
     itemView.setBackgroundColor(defaultBackgroundColor); 
     ImageView iv = (ImageView) itemView.findViewById(R.id.imageView1); 
     if (iv != null) 
      iv.setVisibility(View.VISIBLE); 
    } 
}; 

private class LoadList extends AsyncTask<Void, Void, Void> { 

    public LoadList() { 
     execute(); 
    } 

    @Override 
    protected void onPreExecute() { 
     String[] x = { "Loading..." }; 
     addNewTTD(); 
     ArrayAdapter<String> asdf = new ArrayAdapter<String>(
       PlanDayScreen.this, R.layout.add_more, x); 
     lista.setAdapter(asdf); 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 
     ScheduledThingToDo[] ttds; 
     try { 
      try { 
       // Loads current day 
       day = Planner.loadDay(CurrentItemsStorage.currentDay); 
       ttds = day.ttds; 
      } catch (NullPointerException ex) { 
       // No current day: Loads today 
       Day day = Planner.loadDay(Calendar.getInstance()); 
       ttds = day.ttds; 
      } 
     } catch (OfflineException e) { 
      // Offline 
      Toast.makeText(PlanDayScreen.this, 
        getResources().getString(R.string.day_error), 
        Toast.LENGTH_SHORT).show(); 
      ttds = new ScheduledThingToDo[0]; 
     } catch (UnauthorizedException e) { 
      // Something strange happened 
      ttds = new ScheduledThingToDo[0]; 
     } catch (Exception e) { 
      // Something even more strange happened 
      ttds = new ScheduledThingToDo[0]; 
     } 

     adapter = new DragNDropAdapter(PlanDayScreen.this, 
       new int[] { R.layout.dragitemttd }, ttds); 

     adapter.setOnCheckListener(new OnCheckListener() { 

      @Override 
      public void onCheck(boolean isChecked, int position) { 
       checkedBoxes.set(position, isChecked); 
       setUpBottomLayout(areThereCheckedBoxes()); 
      } 
     }); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     lista.setAdapter(adapter); 
     lista.setDropListener(mDropListener); 
     lista.setRemoveListener(mRemoveListener); 
     lista.setDragListener(mDragListener); 

    } 

} 

private class DropCall extends AsyncTask<Void, Void, Void> { 

    private int from, to; 

    public DropCall(int from, int to) { 
     this.from = from; 
     this.to = to; 
     execute(); 
     lista.invalidateViews(); 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 
     changeScheduledTTD(from, to); 
     return null; 
    } 

    /** 
    * Unschedules a TTD and then re-schedules it in its proper place 
    * 
    * @param from 
    *   The position the TTD came from 
    * @param to 
    *   The position the TTD has been dragged to 
    */ 
    protected void changeScheduledTTD(int from, int to) { 
     ScheduledThingToDo currentTTD; 
     if (adapter.getItem(to) instanceof ScheduledThingToDo) 
      currentTTD = (ScheduledThingToDo) adapter.getItem(to); 
     else 
      return; 

     int indexMorning = 0; 
     int indexAfternoon = 0; 
     int indexEvening = 0; 
     Object item = null; 
     String currentTime = null; 
     // Gets the indexes for Morning, Afternoon and Evening 
     for (int i = 0; i < adapter.getCount(); i++) { 
      item = adapter.getItem(i); 
      if (item instanceof String) { 
       currentTime = (String) item; 
       if (currentTime.equals("MORNING")) { 
        indexMorning = i; 
       } 
       if (currentTime.equals("AFTERNOON")) { 
        indexAfternoon = i; 
       } 
       if (currentTime.equals("EVENING")) { 
        indexEvening = i; 
       } 
      } 
     } 

     TimeOfDay tod = null; 
     if (to >= indexEvening) { 
      tod = TimeOfDay.evening; 
     } else if (to >= indexAfternoon) { 
      tod = TimeOfDay.afternoon; 
     } else if (to >= indexMorning) { 
      tod = TimeOfDay.morning; 
     } 
     if (!currentTTD.time.getTimeOfDay().equals(tod)) { 

      try { 
       Planner.unschedule(currentTTD.ttdId, currentTTD.time); 
       Planner.schedule(currentTTD.ttdId, new ScheduledTime(
         CurrentItemsStorage.currentDay, tod)); 
      } catch (OfflineException e) { 
       e.printStackTrace(); 
      } 

     } 
    } 
} 
} 
+0

puoi fornirci il codice della tua attività? – AMerle

+0

Fatto. Però è lungo ,-); l'eccezione è lanciata alla prima riga di codice sulla dichiarazione di mDragListener. – razielsarafan

+0

stai provando a correre dopo la pulizia del progetto? –

risposta

7

tuo mDragListener è una variabile membro. Al momento dell'inizializzazione, l'oggetto/istanza Activity potrebbe non essere pronto. Quindi chiamare getResource() dell'attività non funzionerà.

// inner class or normal class ... change scope if needed 
private class DragListener { 
    int color = 0; 
    public DragListener(Context context) { 
     color = context.getResource().getColor(R.color.yellow); 
    } 
} 

// activity 
private DragListener mDragListener; 
public void onCreate(...) { 
    mDragListener = new DragListener(this); 
    // more code 
} 
+0

Quali sono le mie opzioni allora? – razielsarafan

+0

Imposta DragListener come classe interna privata con un costruttore che ha un parametro di contesto. All'interno del costruttore, inizializza i colori usando 'context.getResource()'. Quindi inizializza la variabile listener nel onCreate della tua attività. Le definizioni di classi anonime come te non sono riutilizzabili e quindi solo sufficienti in situazioni molto specifiche. Cerco sempre di rendere le classi riutilizzabili. – WarrenFaith

-4
int backgroundColor = Color.YELLOW; 

invece di

int backgroundColor = getResources().getColor(R.color.yellow); 
+3

Chi ha detto che "R.color.yellow == Color.YELLOW'? – WarrenFaith

+1

R.colore giallo non è colore. GIALLO. Neanche vicino. – razielsarafan

+0

Questa non è una soluzione al problema degli OP. Il suo problema era chiamare getResources() prima che il contesto fosse inizializzato. –

Problemi correlati