安卓:初始化期间出现空指针异常



我试图调试这个问题,但对为什么我得到空指针异常错误感到非常困惑。我在代码中声明 checkBTStates() 方法的行不断收到错误(是的,我已经尽我所能完成了这个以确保一切正常)

下面是我的片段、活动和错误代码。我希望我能更好地粘贴代码。不好意思。

片段

package edu.umass.ecs.chalkmaster3000;
import android.app.Activity;
import android.app.Fragment;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.IOException;
import java.util.UUID;
public class HomeFragment extends Fragment {
public static final int BT_ACTIVITY = 5;
public int i;
ActivityCommunication activityCallback;
public interface ActivityCommunication{
    public void updateColors(int color);
    public String getAddress();
    public UUID getUUID();
    public BluetoothSocket getBTSocket();
    public BluetoothAdapter getBTAdapter();
    public void setConnectionStatus(boolean status);
    public View getView(int viewID);
    public Context getContext();
}
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        activityCallback = (ActivityCommunication) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement ActivityCommunication");
    }
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
   View V = inflater.inflate(R.layout.home_fragment,container,false);
    ImageView robotImage = (ImageView) V.findViewById(R.id.robotStatus);
   //checkBTStates();
    if(BluetoothAdapter.getDefaultAdapter()==null){
        V.setBackgroundColor(getResources().getColor(R.color.orange));
        robotImage.setImageResource(R.drawable.red_robot);
        activityCallback.updateColors(0);
        activityCallback.setConnectionStatus(false);
    }
    else{
        V.setBackgroundColor(getResources().getColor(R.color.red));
        robotImage.setImageResource(R.drawable.red_robot);
        activityCallback.updateColors(2);
        activityCallback.setConnectionStatus(false);
    }
    final Button button = (Button) V.findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            checkBTStates();
        }
    });
    return V;
}
private void checkBTStates() {
      BluetoothAdapter btAdapter = activityCallback.getBTAdapter();
    View currentView = activityCallback.getView(R.id.home_fragment);
    ImageView robotImage = (ImageView) activityCallback.getView(R.id.robotStatus);
    // Check for Bluetooth support and then check to make sure it is turned on
    if(btAdapter==null) {
        Toast toast = Toast.makeText(activityCallback.getContext(), "Fatal Error: Bluetooth doesn't seem to be supported on your device! :(", Toast.LENGTH_LONG);
        toast.show();
        currentView.setBackgroundColor(getResources().getColor(R.color.orange));
        activityCallback.updateColors(0);
        activityCallback.setConnectionStatus(false);
        robotImage.setImageResource(R.drawable.red_robot);
    }
    else {
            if (btAdapter.isEnabled()) {
                connectBT();
                }
            else {
                    //Prompt user to turn on Bluetooth
                    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableBtIntent, BT_ACTIVITY);
            }
    }
}
BluetoothSocket btSocket = activityCallback.getBTSocket();
private void connectBT(){
    BluetoothAdapter btAdapter = activityCallback.getBTAdapter();
    View currentView = activityCallback.getView(R.id.home_fragment);
    ImageView robotImage = (ImageView) activityCallback.getView(R.id.robotStatus);

    // Two things are needed to make a connection:
    //   A MAC address, which we got above.
    //   A Service ID or UUID.  In this case we are using the
    //     UUID for SPP.

    // Discovery is resource intensive.  Make sure it isn't going on
    // when you attempt to connect and pass your message.
    btAdapter.cancelDiscovery();
    // Establish the connection.  This will block until it connects.
    try {
        btSocket.connect();
        Toast toast = Toast.makeText(activityCallback.getContext(), "Connection established and data link opened...", Toast.LENGTH_LONG);
        toast.show();
        currentView.setBackgroundColor(getResources().getColor(R.color.blue));
        activityCallback.updateColors(1);
        robotImage.setImageResource(R.drawable.green_robot);
        activityCallback.setConnectionStatus(true);
    } catch (IOException e) {
        try {
            currentView.setBackgroundColor(getResources().getColor(R.color.red));
            activityCallback.updateColors(2);
            robotImage.setImageResource(R.drawable.red_robot);
            activityCallback.setConnectionStatus(false);
            btSocket.close();
        } catch (IOException e2) {
            Toast toast = Toast.makeText(activityCallback.getContext(),"Fatal Error in onResume() and unable to close socket during connection failure" + e2.getMessage() + ".", Toast.LENGTH_LONG);
            toast.show();
        }
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    View currentView = activityCallback.getView(R.id.home_fragment);
    ImageView robotImage = (ImageView) activityCallback.getView(R.id.robotStatus);
    switch(requestCode){
        case BT_ACTIVITY:
            if(resultCode == -1){
                i = 50; //Stop asking the user to enable bluetooth
                connectBT();
                Toast.makeText(activityCallback.getContext(), "Bluetooth is now on!", Toast.LENGTH_SHORT).show();
            }
            else if(resultCode == 0){
                currentView.setBackgroundColor(getResources().getColor(R.color.red));
                activityCallback.updateColors(2);
                robotImage.setImageResource(R.drawable.red_robot);
                activityCallback.setConnectionStatus(false);
                Toast toast = Toast.makeText(activityCallback.getContext(), "This application requires Bluetooth...Maybe try to turn it on?! ;)", Toast.LENGTH_LONG);
                toast.show();
            }
        break;
    }
}
}

活动

package edu.umass.ecs.chalkmaster3000;

 public class MainActivity extends FragmentActivity implements HomeFragment.ActivityCommunication , GalleryFragment.ActivityCommunication {
    private String[] viewTitles;
    private DrawerLayout drawerLayout;
    private ListView drawerList;
    private CharSequence currentTitle;
    private CharSequence drawerTitle;
    private ActionBarDrawerToggle drawerToggle;
    public boolean connectionStatus = false;

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
   public void onCreate(Bundle savedInstanceStates){
    super.onCreate(savedInstanceStates);
    setContentView(R.layout.activity_main);
    currentTitle=drawerTitle=getTitle();
    viewTitles = getResources().getStringArray(R.array.view_names);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerList = (ListView) findViewById(R.id.left_drawer);
    // set a custom shadow that overlays the gallery content when the drawer opens
    drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
    drawerList.setAdapter(new ArrayAdapter<String>(this,R.layout.drawer_list_item, viewTitles));
    drawerList.setOnItemClickListener(new DrawerItemClickListener());
    // enable ActionBar app icon to behave as action to toggle nav drawer
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    drawerToggle = new ActionBarDrawerToggle(
            this,
            drawerLayout,
            R.drawable.ic_drawer,
            R.string.drawer_open,
            R.string.drawer_close
            ) {
        /* Called when a drawer has settled in a completely closed state. */
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(currentTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
        /* Called when a drawer has settled in a completely open state. */
        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(drawerTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
    };
    /* Set the drawer toggle as the DrawerListener */
    drawerLayout.setDrawerListener(drawerToggle);
    if (savedInstanceStates == null) {
        selectItem(0);
    }

}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    // If the nav drawer is open, hide action items related to the content view
    boolean drawerOpen = drawerLayout.isDrawerOpen(drawerList);
    menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Pass the event to ActionBarDrawerToggle, if it returns
    // true, then it has handled the app icon touch event
    if (drawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action buttons
    switch(item.getItemId()) {
        case R.id.action_websearch:
            // create intent to perform web search for this planet
            Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
            intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
            // catch event that there's no activity to handle intent
             if (intent.resolveActivity(getPackageManager()) != null) {
                startActivity(intent);
            } else {
                Toast.makeText(this, "notavail", Toast.LENGTH_LONG).show();
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
/* The click listener for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }
}
private void selectItem(int position){
    Fragment fragment;
    /* Clicked Home Button*/
    if(position == 0){
        fragment = new HomeFragment();
    }
    /* Clicked Canvas Button*/
    else if(position == 1){
        fragment = new CanvasFragment();
    }
          /* Clicked Canvas Button*/
    else if(position == 2){
        fragment = new GalleryFragment();
    }
    /* Clicked Pre-Made Button*/
    else if(position == 3){
        fragment = new PreMadeFragment();
    }
    /* Clicked Robot Status Button*/
    else{
        fragment = new RoboStatusFragment();
    }
    /* Update Main Activity with new Fragment*/
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction()
            .replace(R.id.content_frame, fragment)
            .commit();
    /* Highlight the icon selected, Close the Navigation Drawer, and Update the Title */
    drawerList.setItemChecked(position,true);
    setTitle(viewTitles[position]);
    drawerLayout.closeDrawer(drawerList);
}
public void updateColors(int color){
    if(color == 0)
        findViewById(R.id.content_frame).getRootView().setBackgroundColor(getResources().getColor(R.color.orange));
    else if(color == 1)
        findViewById(R.id.content_frame).getRootView().setBackgroundColor(getResources().getColor(R.color.blue));
    else
        findViewById(R.id.content_frame).getRootView().setBackgroundColor(getResources().getColor(R.color.red));
}
public UUID getUUID(){
    //Well known SPP UUID
    final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    return MY_UUID;
}
public String getAddress(){
    //MAC Address of the Server BT Adapter
    String address = "B8:F6:B1:13:57:B8";
    return address;
}
public BluetoothAdapter getBTAdapter(){
    BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
    return btAdapter;
}
public BluetoothSocket getBTSocket(){
    // Set up a pointer to the remote node using it's address.
    BluetoothDevice device = this.getBTAdapter().getRemoteDevice(this.getAddress());
    BluetoothSocket btSocket = null;
    try {
        btSocket = device.createRfcommSocketToServiceRecord(this.getUUID());
    } catch (IOException e) {
        Toast toast = Toast.makeText(this, "Fatal Error in onResume() and socket create failed: " + e.getMessage() + ".", Toast.LENGTH_LONG);
        toast.show();
    }
    return btSocket;
}
public void setConnectionStatus(boolean status){
    connectionStatus = status;
}
public boolean getConnectionStatus(){
    return connectionStatus;
}
public View getView(int viewID){
    return findViewById(viewID);
}
   @Override
public void setTitle(CharSequence newTitle){
   currentTitle = newTitle;
   getActionBar().setTitle(currentTitle);
   }
@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    drawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    drawerToggle.onConfigurationChanged(newConfig);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
}
}

错误

  Caused by: java.lang.NullPointerException
        at edu.umass.ecs.chalkmaster3000.HomeFragment.<init>(HomeFragment.java:84)
        at edu.umass.ecs.chalkmaster3000.MainActivity.selectItem(MainActivity.java:153)
        at edu.umass.ecs.chalkmaster3000.MainActivity.onCreate(MainActivity.java:90)
        at android.app.Activity.performCreate(Activity.java:5372)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2267)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2359)
        at android.app.ActivityThread.access$700(ActivityThread.java:165)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1326)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5455)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
        at dalvik.system.NativeStart.main(Native Method)

感谢您的任何帮助,节日快乐!

您必须

在使用它之前初始化 viewTitles

 viewTitles = new String[];
什么是

必须为你工作的currentTitle=drawerTitle=getTitle();

如果片段与活动分离,则可以在调用getActivity()时获得nullPointerException

公共最终活动获取活动 () 在 API 级别 11 中添加

返回此片段当前关联的活动。

参考这个答案:

安卓获取活动返回空

是的,这是真的。但是你的错误不在Java上,而是来自XML。来自安卓(文档)[http://developer.android.com/training/implementing-导航/导航抽屉.html]

1: The main content view (the FrameLayout above) must be the first child in the 
DrawerLayout because the XML order implies z-ordering and the drawer must be 
on top of the content.
2: The main content view is set to match the parent view's width and height, because 
it represents the entire UI when the navigation drawer is hidden.

因此,从本文档中,您的 XML 应包含抽屉布局,框架布局应包含您的活动主视图

,其顺序是
R.id.Content_frame
布局

应为活动布局的视图组或父视图。

最新更新