在活动之间共享变量的问题

时间:2017-03-11 21:17:43

标签: java android nullpointerexception

代码是从https://github.com/hastarin/android-udpsender大量借用的,而且他的代码非常通用,我想要一个简单的方法将一个udp数据包发送到一个能解锁车库门的Arduino。

基本上第一页(MainActivity)有一个很大的" Open"按钮和一个小" Set Params"按钮。第二页(Main2Activity)主要是带有批量删除的借用代码,并提供了输入IP地址,端口和解锁代码字的方法。目前有"发送"将已组装的udp数据包发送到客户端的按钮,它按预期工作。

问题是我真的不想定期访问第二页。我需要" sendData" MainActivity中的例程,可以访问存储的值进行处理。

此时,按MainActivity页面上的Send按钮会导致:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
    at com.kke.android.opener.MainActivity.sendData(MainActivity.java:47)
    at com.kke.android.opener.MainActivity.onClick(MainActivity.java:30)

我认为该变量值对该页面上的sendData例程不可用。

MainActivity

package com.kke.android.opener;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements View.OnClickListener{

private View view;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button btnsend = (Button) findViewById(R.id.buttonSend);
    Button btnset = (Button) findViewById(R.id.buttonSet);
    btnsend.setOnClickListener(this);
    btnset.setOnClickListener(this);
}
 @Override
 public void onClick(View v) {
     switch (v.getId()) {
         case R.id.buttonSend:
             sendData(v);
             break;

         case R.id.buttonSet:
             editParams(view);
             break;
     }
 }


public void sendData(View view) {
    Context context = getApplicationContext();

   /**Load global variable from Main2Activity*/

   Bundle bundle = getIntent().getExtras();
   String host = bundle.getString("host");
   String port = bundle.getString("port");
   String dataText = bundle.getString("dataText");

    //EditText editText = (EditText) findViewById(R.id.editTextIP);
    //String host = editText.getText().toString();
    if (!host.matches("\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b")) {
        CharSequence text = "Error: Invalid IP Address";
        Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        toast.show();
        return;
    }
    //editText = (EditText) findViewById(R.id.editTextPort);
    //String port = editText.getText().toString();
    if (!port.matches("^(6553[0-5]|655[0-2]\\d|65[0-4]\\d\\d|6[0-4]\\d{3}|[1-5]\\d{4}|[1-9]\\d{0,3}|0)$")) {
        CharSequence text = "Error: Invalid Port Number";
        Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        toast.show();
        return;
    }
   // editText = (EditText) findViewById(R.id.editTextData);
    //String dataText = editText.getText().toString();
    if (dataText.length() < 1 ) {
        CharSequence text = "Error: Text required to send";
        Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        toast.show();
        return;
    }
    String uriString = "udp://" + host + ":" + port + "/";
    uriString += Uri.encode(dataText);

    Uri uri = Uri.parse(uriString);
    Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
    intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
    intent.addCategory(Intent.CATEGORY_DEFAULT);

    startActivity(intent);
}

    /** Called when the user taps the Set Params button */

    public void editParams(View view) {
        Intent intent = new Intent(this, Main2Activity.class);
        startActivity(intent);
    }

}

Main2Activity

package com.kke.android.opener.ui;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.text.InputType;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.kke.android.opener.R;

public class Main2Activity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Restore preferences
    SharedPreferences settings = getPreferences(0);
    ToggleButton toggleButton = ((ToggleButton) findViewById(R.id.toggleButton));
    boolean checked = settings.getBoolean("toggleChecked", false);
    toggleButton.setChecked(checked);
    toggleButton.setVisibility(View.GONE);
    EditText editText = (EditText) findViewById(R.id.editTextIP);
    if (checked) {
        editText.setInputType(InputType.TYPE_CLASS_TEXT);
    }
    editText.setText(settings.getString("host", ""), TextView.BufferType.EDITABLE);
    editText = (EditText) findViewById(R.id.editTextPort);
    if (checked) {
        editText.setInputType(InputType.TYPE_CLASS_TEXT);
    }
    editText.setText(settings.getString("port", ""), TextView.BufferType.EDITABLE);
    editText = (EditText) findViewById(R.id.editTextData);
    editText.setText(settings.getString("dataText", ""), TextView.BufferType.EDITABLE);

    /** Set up global variable to pass to MainActivity */

     Intent intent = new Intent(Main2Activity.this, MainActivity.class);
     intent.putExtra("host", "host");
     intent.putExtra("port", "port");
     intent.putExtra("dataText", "dataText");
     startActivity(intent);

}

@Override
public void onPause() {
    super.onPause();

    // Get current values
    EditText editText = (EditText) findViewById(R.id.editTextIP);
    String host = editText.getText().toString();
    editText = (EditText) findViewById(R.id.editTextPort);
    String port = editText.getText().toString();
    editText = (EditText) findViewById(R.id.editTextData);
    String dataText = editText.getText().toString();



    // We need an Editor object to make preference changes.
    // All objects are from android.context.Context
    SharedPreferences settings = getPreferences(0);
    SharedPreferences.Editor editor = settings.edit();
    editor.putString("host", host);
    editor.putString("port", port);
    editor.putString("dataText", dataText);
    editor.putBoolean("toggleChecked", ((ToggleButton) findViewById(R.id.toggleButton)).isChecked());

    // Commit the edits!
    editor.commit();
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
        case R.id.action_send:
            this.sendData(null);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

public void sendData(View view) {
    Context context = getApplicationContext();

    EditText editText = (EditText) findViewById(R.id.editTextIP);
    String host = editText.getText().toString();
    if (!host.matches("\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b")) {
        CharSequence text = "Error: Invalid IP Address";
        Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        toast.show();
        return;
    }
    editText = (EditText) findViewById(R.id.editTextPort);
    String port = editText.getText().toString();
    if (!port.matches("^(6553[0-5]|655[0-2]\\d|65[0-4]\\d\\d|6[0-4]\\d{3}|[1-5]\\d{4}|[1-9]\\d{0,3}|0)$")) {
        CharSequence text = "Error: Invalid Port Number";
        Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        toast.show();
        return;
    }
    editText = (EditText) findViewById(R.id.editTextData);
    String dataText = editText.getText().toString();
    if (dataText.length() < 1 ) {
        CharSequence text = "Error: Text/Hex required to send";
        Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        toast.show();
        return;
    }
    String uriString = "udp://" + host + ":" + port + "/";
    uriString += Uri.encode(dataText);

    Uri uri = Uri.parse(uriString);
    Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
    intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
    intent.addCategory(Intent.CATEGORY_DEFAULT);

    startActivity(intent);
}

public void onToggleClicked(View view) {
    boolean on = ((ToggleButton) view).isChecked();


    EditText editTextIp = (EditText) findViewById(R.id.editTextIP);
    EditText editTextPort = (EditText) findViewById(R.id.editTextPort);
    if (on) {
        editTextIp.setInputType(InputType.TYPE_CLASS_TEXT);
        editTextPort.setInputType(InputType.TYPE_CLASS_TEXT);
    } else {
        editTextIp.setInputType(InputType.TYPE_CLASS_PHONE);
        editTextPort.setInputType(InputType.TYPE_CLASS_PHONE);
    }
 }
}

所有建议将不胜感激。 请记住我对此很新。

2 个答案:

答案 0 :(得分:1)

你的两个活动都有完全相同的布局......这可能令人困惑......

无论如何,当没有额外的东西(刚开始的那个活动)时,你打电话给getIntent().getExtras()

您的代码示例

   Bundle bundle = getIntent().getExtras();
   String host = bundle.getString("host");
   String port = bundle.getString("port");
   String dataText = bundle.getString("dataText");

你可以简单地这样做

Bundle extras = getIntent().getExtras();
// TODO: declare some variables here
String host, port, text;
if (extras != null) {
    // TODO: assign your variables here
   String host = extras.getString("host");
   String port = extras.getString("port");
   String dataText = extras.getString("dataText");
}

然而,如果你因为意图仍然是空的而得不到任何东西,不要感到惊讶

答案 1 :(得分:1)

发生的事情是您的MainActivity可能是从Android启动器启动的,而不是从MainActivity2启动的。

基本上,当您单击“发送”时,您将检查将您带到此处的意图(对此活动)。由于您来自启动程序,因此该意图没有执行该函数所需的数据。请记住,您正在MainActivity2中设置此意图的数据(在您的oncreate方法上,这在此上下文中是一种不好的做法)。

要解决此问题,请转到清单并将MainActivity2作为启动器活动:

<activity android:name="<YOUR_ACTIVITY_TWO_NAME">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

这将确保首先调用您的Activity2,这将链接到MainActivity并发送具有实际数据的意图。