5

当我尝试getResources().getColor(R.color.yellow)在正常活动中获取颜色时,我得到了这个异常:

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

有人可以在这里给我一些后见之明吗?我完全迷路了。

活动中的代码:

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();
            }

        }
    }
}
}
4

2 回答 2

7

mDragListener是一个成员变量。在初始化 Activity 对象/实例时可能还没有准备好。所以调用getResource()Activity 会失败。

// 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
}
于 2012-07-12T10:18:37.260 回答
-4
int backgroundColor = Color.YELLOW;

代替

int backgroundColor = getResources().getColor(R.color.yellow);
于 2012-07-12T10:16:29.763 回答