Android:初始化期间的空指针异常

时间:2013-12-27 17:33:29

标签: android android-fragments nullpointerexception initialization

我试图调试这个问题,但我很困惑为什么我得到一个Null Pointer Exception错误。我一直在我的代码中的行中获取错误,其中声明了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)

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

3 个答案:

答案 0 :(得分:0)

您必须在使用之前初始化 viewTitles

 viewTitles = new String[];

什么是currentTitle=drawerTitle=getTitle();必须为你工作?

答案 1 :(得分:0)

如果片段与活动分离,则在调用getActivity()时可能会收到nullPointerException

  

public final Activity getActivity()在API级别11中添加

     

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

参考这个答案:

android get activity returns null

答案 2 :(得分:0)

是的,它是真的..但你的错误不是java来自xml。来自android(文档)[http://developer.android.com/training/implementing-navigation/nav-drawer.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应该包含抽屉布局,而framelayout应该按照那个顺序包含你的活动主视图

R.id.Content_frame

布局应该是您的活动布局的视图组或父视图..