Starting a 3rd Activity setting up interfaces and

2019-09-21 17:03发布

问题:

This question already has an answer here:

  • What is a NullPointerException, and how do I fix it? 12 answers

So my MainActivity was able to start my second activity from a btn click fine. Now on my second activity, I have a drag and drop type game where what I want is one the correct image was dropped, I want it to start a 3rd Activity but I am getting a java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference

This is my code from my main which starts the 2nd activity. this works fine.

public void onClickadjectives(View v4) {

MainActivitytest.this.startActivity(new Intent(MainActivitytest.this, DragActivityV2.class));
}

Now on the second class, I have a HELPER class that determines the correct drop spot

public class DropSpot extends MyAbsoluteLayout
implements DropTarget, DragController.DragListener
{  // codes...
if (controller != null) {
   controller.setDragListener (this);
   controller.addDropTarget (this);
    System.out.println("Correct Spot");

    DragActivityV2 ca = new DragActivityV2();
    ca.correctAns();

}

And now this is my second activity

    public class DragActivityV2 extends Activity
            implements View.OnLongClickListener, View.OnClickListener, View.OnTouchListener
    {       //more codes...
    public void correctAns()

        {
            Context context;
            Intent intent = new Intent(this, FallAnimationActivity.class);
            DragActivityV2.this.startActivity(intent);
            finish();
        }

when I run it, it crashes when i click on the btn to go to my second activity. This is the error

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: info.androidhive.tabsswipe, PID: 4141
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{info.androidhive.tabsswipe/info.androidhive.tabsswipe.dragview.DragActivityV2}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
                      at android.app.ActivityThread.-wrap12(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6119)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                      at android.content.ContextWrapper.getPackageName(ContextWrapper.java:132)
                      at android.content.ComponentName.<init>(ComponentName.java:128)
                      at android.content.Intent.<init>(Intent.java:4900)
                      at info.androidhive.tabsswipe.dragview.DragActivityV2.correctAns(DragActivityV2.java:548)
                      at info.androidhive.tabsswipe.dragview.DropSpot.setup(DropSpot.java:346)
                      at info.androidhive.tabsswipe.dragview.DragActivityV2.setupViews(DragActivityV2.java:456)
                      at info.androidhive.tabsswipe.dragview.DragActivityV2.onCreate(DragActivityV2.java:104)
                      at android.app.Activity.performCreate(Activity.java:6679)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
                      at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:154) 
                      at android.app.ActivityThread.main(ActivityThread.java:6119) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
Application terminated.

Now if i remove the calling of method and just put it on a button, it works fine. But i really want it to go to the 3rd activity ONLY if the correct img was dropped.

Can anyone PLEASE help me thank you so much in advance.

EDIT I added most of my 2nd activity codes...

public class DragActivityV2 extends Activity
        implements View.OnLongClickListener, View.OnClickListener, View.OnTouchListener

// Constants

    private static final int ENABLE_S2_MENU_ID = Menu.FIRST;
    private static final int DISABLE_S2_MENU_ID = Menu.FIRST + 1;
    private static final int ADD_OBJECT_MENU_ID = Menu.FIRST + 2;
    private static final int CHANGE_TOUCH_MODE_MENU_ID = Menu.FIRST + 3;

    public int ind = 0;
    public String[] myShuffledArray;
    public String[] quesDescription;
    public Context context;
    public MyDBEmbrASD db;
    public String selectedImg;
    public int dmw;
    public int dmh;

    /**
     */
// Variables

    private DragController mDragController;   // Object that sends out drag-drop events while a view is being moved.
    private DragLayer mDragLayer;             // The ViewGroup that supports drag-drop.
    private DropSpot mSpot2;                  // The DropSpot that can be turned on and off via the menu.

    private boolean mLongClickStartsDrag = false;    // If true, it takes a long click to start the drag operation.
    public boolean showbutton = false;
    // Otherwise, any touch event starts a drag.


    public static final boolean Debugging = false;
    private DragController controller;

   @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        super.onCreate(savedInstanceState);
        mDragController = new DragController(this);

        setContentView(R.layout.main);
        setupViews ();
    }

public boolean onTouch (View v, MotionEvent ev)
{
    // If we are configured to start only on a long click, we are not going to handle any events here.
    if (mLongClickStartsDrag) return false;

    boolean handledHere = false;

    final int action = ev.getAction();

    // In the situation where a long click is not needed to initiate a drag, simply start on the down event.
    if (action == MotionEvent.ACTION_DOWN) {
       handledHere = startDrag (v);


        System.out.println("value of selectedTag ID " + v.getTag());
        System.out.println("value of corrAns " + selectedImg );
        if (v.getTag() != selectedImg)
        {
            mSpot2.setDragLayer(null);
        }
        else
        {
            mSpot2.setDragLayer(mDragLayer);
            System.out.println("Correct Answer!");

        }

    }
    return handledHere;
}

/**
 * Start dragging a view.
 *
 */

public boolean startDrag (View v)
{
    // Let the DragController initiate a drag-drop sequence.
    // I use the dragInfo to pass along the object being dragged.
    // I'm not sure how the Launcher designers do this.
    Object dragInfo = v;
    mDragController.startDrag (v, mDragLayer, dragInfo, DragController.DRAG_ACTION_MOVE);
    return true;
}


public boolean onTouch (View v, MotionEvent ev)
{
    // If we are configured to start only on a long click, we are not going to handle any events here.
    if (mLongClickStartsDrag) return false;

    boolean handledHere = false;

    final int action = ev.getAction();

    // In the situation where a long click is not needed to initiate a drag, simply start on the down event.
    if (action == MotionEvent.ACTION_DOWN) {
       handledHere = startDrag (v);


        System.out.println("value of selectedTag ID " + v.getTag());
        System.out.println("value of corrAns " + selectedImg );
        if (v.getTag() != selectedImg)
        {
            mSpot2.setDragLayer(null);
        }
        else
        {
            mSpot2.setDragLayer(mDragLayer);
            System.out.println("Correct Answer!");

        }

    }
    return handledHere;
}


public boolean startDrag (View v)
{
    // Let the DragController initiate a drag-drop sequence.
    // I use the dragInfo to pass along the object being dragged.
    // I'm not sure how the Launcher designers do this.
    Object dragInfo = v;
    mDragController.startDrag (v, mDragLayer, dragInfo,

    DragController.DRAG_ACTION_MOVE);
        return true;
    }

private void setupViews()
{
    DragController dragController = mDragController;

    mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
    mDragLayer.setDragController(dragController);
    dragController.addDropTarget (mDragLayer);

    context = this;
    db = new MyDBEmbrASD(this);


    String[] myShuffledArray = new Extract().invoke();

    List<QuestionGetterSetter> resources3 = db.QuestionGetterSetter();
    int numQues = resources3.size();
    String[] quesNum = new String[resources3.size()];
    String[] quesDesc = new String[resources3.size()];
    String[] corrAnsr = new String[resources3.size()];
    String[] corrAnsIMPID = new String[resources3.size()];
    String[] lessnModule = new String[resources3.size()];

    System.out.println("TESTESTESTESTESTEST");
    for (int i = 0; i < resources3.size(); i++) {
        quesNum[i] = resources3.get(i).getQuesNum();
        quesDesc[i] = resources3.get(i).getquesDesc();
        corrAnsr[i] = resources3.get(i).getcorrAns();
        corrAnsIMPID[i] = resources3.get(i).getcorrAnsIMPID();
        lessnModule[i] = resources3.get(i).getlessnModule();
        System.out.println("test + " + quesNum[i]);
        System.out.println("test + " + quesDesc[i]);
        System.out.println("test + " + corrAnsr[i]);
        System.out.println("test + " + corrAnsIMPID[i]);
        System.out.println("test + " + lessnModule[i]);
    }


    Random rQuestion = new Random();
    int iQues = rQuestion.nextInt(numQues - 1)+1;
    System.out.println("testCorrAnsr " + corrAnsIMPID[iQues]);
    System.out.println("testCorrAnsr " + corrAnsr[0]);
    selectedImg = corrAnsIMPID[iQues];
    System.out.println("corrAnsIMPID" + selectedImg);
    int id5 = getResources().getIdentifier(corrAnsIMPID[iQues], "drawable", getPackageName());
    System.out.println ("img1id" + id5);



    ArrayList<String> quesList = new ArrayList<>();

    quesList.add(corrAnsIMPID[iQues]);
    quesList.add(myShuffledArray[rQuestion.nextInt(numQues - 1) + 1]);
    quesList.add(myShuffledArray[rQuestion.nextInt(numQues - 1) + 1]);
    quesList.add(myShuffledArray[rQuestion.nextInt(numQues - 1) + 1]);
    Collections.shuffle(quesList);

    String[] ranQues = new String[quesList.size()];
    ranQues = quesList.toArray(ranQues);
    for(String s : ranQues);
    System.out.println("test ranques" + ranQues[0]);
    System.out.println("test ranques" + ranQues[1]);
    System.out.println("test ranques" + ranQues[2]);
    System.out.println("test ranques" + ranQues[3]);

    DisplayMetrics size = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(size );
    dmw = size .widthPixels;
    dmh = size .heightPixels;

    System.out.println("displaymetrics w" + dmw);
    System.out.println("displaymetrics h" + dmh);

    /////
    ImageView newView1 = new ImageView(this);
    int id1 = getResources().getIdentifier(ranQues[0], "drawable", getPackageName());
    newView1.setImageResource(id1);
    //newView1.setImageResource (android.R.drawable.alert_dark_frame);
    Random r = new Random();
    int w1 = (int) (dmw*.2)+50;
    int h1 = (int) (dmh*.2)+50;
    int left1 =r.nextInt((int) (dmw - ((dmw*.3)+50))) + 0;
    int top1 = r.nextInt((int) (dmh - ((dmh*.4)+50))) + 0;
    DragLayer.LayoutParams lp1 = new DragLayer.LayoutParams (w1, h1, left1, top1);

    mDragLayer.addView (newView1, lp1);
    newView1.setOnClickListener(this);
    newView1.setOnLongClickListener(this);
    newView1.setOnTouchListener(this);
    newView1.setTag(ranQues[0]);
    String imgTag1 = (String) newView1.getTag();
    System.out.println("imgTag 1" + imgTag1);

    System.out.println ("img1id" + newView1.getId());
    /////

    /////
    ImageView newView2 = new ImageView(this);
    int id2 = getResources().getIdentifier(ranQues[1], "drawable", getPackageName());
    newView2.setImageResource(id2);
    //newView2.setImageResource (android.R.drawable.alert_dark_frame);
    int w2 = (int) (dmw*.2)+50;
    int h2 = (int) (dmh*.2)+50;
    int left2 =r.nextInt((int) (dmw - ((dmw*.3)+50))) + 0;
    int top2 = r.nextInt((int) (dmh - ((dmh*.4)+50))) + 0;
    DragLayer.LayoutParams lp2 = new DragLayer.LayoutParams (w2, h2, left2, top2);
    mDragLayer.addView (newView2, lp2);
    newView2.setOnClickListener(this);
    newView2.setOnLongClickListener(this);
    newView2.setOnTouchListener(this);
    newView2.setTag(ranQues[1]);
    String imgTag2 = (String) newView2.getTag();
    System.out.println("imgTag 1" + imgTag2);

    System.out.println ("img1id" + newView2.getId());
    /////

    /////
    ImageView newView3 = new ImageView(this);
    int id3 = getResources().getIdentifier(ranQues[2], "drawable", getPackageName());
    newView3.setImageResource(id3);
    //newView3.setImageResource (android.R.drawable.alert_dark_frame);
    int w3 = (int) (dmw*.2)+50;
    int h3 = (int) (dmh*.2)+50;
    int left3 =r.nextInt((int) (dmw - ((dmw*.3)+50))) + 0;
    int top3 = r.nextInt((int) (dmh - ((dmh*.4)+50))) + 0;
    DragLayer.LayoutParams lp3 = new DragLayer.LayoutParams (w3, h3, left3, top3);
    mDragLayer.addView (newView3, lp3);
    newView3.setOnClickListener(this);
    newView3.setOnLongClickListener(this);
    newView3.setOnTouchListener(this);
    newView3.setTag(ranQues[2]);
    String imgTag3= (String) newView3.getTag();
    System.out.println("imgTag 1" + imgTag3);

    System.out.println ("img1id" + newView3.getId());
    /////

    /////
    ImageView newView4 = new ImageView(this);
    int id4 = getResources().getIdentifier(ranQues[3], "drawable", getPackageName());
    newView4.setImageResource(id4);

    //newView4.setImageResource (android.R.drawable.alert_dark_frame);
    int w4 = (int) (dmw*.2)+50;
    int h4 = (int) (dmh*.2)+50;
    int left4 =r.nextInt((int) (dmw - ((dmw*.3)+50))) + 0;
    int top4 = r.nextInt((int) (dmh - ((dmh*.4)+50))) + 0;

    DragLayer.LayoutParams lp4 = new DragLayer.LayoutParams (w4, h4, left4, top4);
    mDragLayer.addView (newView4, lp4);
    newView4.setOnClickListener(this);
    newView4.setOnLongClickListener(this);
    newView4.setOnTouchListener(this);
    newView4.setTag(ranQues[3]);
    String imgTag4 = (String) newView2.getTag();

    System.out.println("imgTag 4" + imgTag4);

    System.out.println ("img1id" + newView4.getId());
    /////


    TextView textView = new TextView(this);
    textView.setText(quesDesc[iQues]);
    textView.setTextSize(25);

    int w = 100;
    int h = 100;
    int left = 0;
    int top = (int) (dmh - ((dmh*.2)+50));
    DragLayer.LayoutParams lp = new DragLayer.LayoutParams (MyAbsoluteLayout.LayoutParams.WRAP_CONTENT, MyAbsoluteLayout.LayoutParams.WRAP_CONTENT, MyAbsoluteLayout.LayoutParams.WRAP_CONTENT, top);
    mDragLayer.addView (textView, lp);


    DropSpot drop2 = (DropSpot) mDragLayer.findViewById (R.id.drop_spot2);
    drop2.setup (null, dragController, R.color.drop_target_color2);
    mSpot2 = drop2;

    mSpot2.mListener = DragActivityV2.this;  //I put this but it said incompatible types




    // Note: It might be interesting to allow the drop spots to be movable too.
    // Unfortunately, in the current implementation, that does not work
    // because the parent view of the DropTarget objects is not the drag layer.
    // The current DragLayer.onDrop method makes assumptions about how to reposition a dropped view.

    // Give the user a little guidance.
    //String message = mLongClickStartsDrag ? "Press and hold to start dragging."
    //                                      : "Touch a view to start dragging.";
    //Toast.makeText (getApplicationContext(), message, Toast.LENGTH_LONG).show ();

}

  public void onRightAnswerSelected() {
        Intent intent = new Intent(this, FallAnimationActivity.class);
                startActivity(intent);
        finish();
    }

}

public interface CorrectAnswerListener {

    void onRightAnswerSelected();

}

回答1:

@Mark, It is not suggestible to implement the architecture in the above way. It is better to use an Interface to acheive this.

Step 1: Create an Interface.

public interface CorrectAnswerListener {

void onRightAnswerSelected();

}

Step 2:

public class DropSpot extends MyAbsoluteLayout
implements DropTarget, DragController.DragListener
{  // codes...

public CorrectAnswerListener mListener; // Set This attribute from //DragActivityV2

if (controller != null) {
   controller.setDragListener (this);
   controller.addDropTarget (this);
    System.out.println("Correct Spot");

    //DragActivityV2 ca = new DragActivityV2();
    //ca.correctAns();

if(mListener != null) {
mListener.onRightAnswerSelected();
}
}

Step 3:

public class DragActivityV2 extends Activity
            implements View.OnLongClickListener, View.OnClickListener, View.OnTouchListener, CorrectAnswerListener;
    {

@override
public void onCreate() {

setContentView();

//Where ever you create an object to helper class, initiate the value as
helperClassObject.mListener = DragActivityV2.this;
}      
//more codes...
    //public void correctAns()

      //  {
        //    Context context;
          //  Intent intent = new Intent(this, FallAnimatio//nActivity.class);
            //DragActivityV2.this.startActivity(intent);
            //finish();


@override
public void onRightAnswerSelected() {
Intent intent = new Intent(this, FallAnimatio//nActivity.class);
startActivity(intent);
finish();
}


回答2:

Do not instantiate Activity with new Activty()

On the DropSpot class get the context of FirstActivity,

public class DropSpot extends MyAbsoluteLayout
implements DropTarget, DragController.DragListener
{  // codes...
if (controller != null) {
   controller.setDragListener (this);
   controller.addDropTarget (this);
    System.out.println("Correct Spot");

    context.startActivtiy(context,DragActivityV2.class);

}

On The DragActivityV2 onCreate call the correctAns()

public class DragActivityV2 extends Activity
            implements View.OnLongClickListener, View.OnClickListener, View.OnTouchListener
    {       //more codes...

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

////code 
correctAns();
    }


public void correctAns()

        {
            Context context;
            Intent intent = new Intent(this, FallAnimationActivity.class);
            DragActivityV2.this.startActivity(intent);
            finish();
        }