问题
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();
}
来源:https://stackoverflow.com/questions/41587155/starting-a-3rd-activity-setting-up-interfaces-and-listeners