2014-10-10 59 views
0

當我的主要活動啓動時,它會給出空指針異常。 我認爲它的wehen我給列表視圖costom適配器。應用程序啓動時的Android空指針異常

logcat的日誌:

10-10 10:07:46.312: D/AbsListView(8971): Get MotionRecognitionManager 
10-10 10:07:46.492: D/AndroidRuntime(8971): Shutting down VM 
10-10 10:07:46.492: W/dalvikvm(8971): threadid=1: thread exiting with uncaught exception (group=0x41fd6ac8) 
10-10 10:07:46.502: E/AndroidRuntime(8971): FATAL EXCEPTION: main 
10-10 10:07:46.502: E/AndroidRuntime(8971): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.csi_week1/com.example.csi_week1.CriminalListActivitie}: java.lang.NullPointerException 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2249) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2299) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.app.ActivityThread.access$700(ActivityThread.java:154) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.os.Handler.dispatchMessage(Handler.java:99) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.os.Looper.loop(Looper.java:137) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.app.ActivityThread.main(ActivityThread.java:5306) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at java.lang.reflect.Method.invokeNative(Native Method) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at java.lang.reflect.Method.invoke(Method.java:511) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at dalvik.system.NativeStart.main(Native Method) 
10-10 10:07:46.502: E/AndroidRuntime(8971): Caused by: java.lang.NullPointerException 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.widget.ListView.setAdapter(ListView.java:469) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at com.example.csi_week1.CriminalListActivitie.onCreate(CriminalListActivitie.java:22) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.app.Activity.performCreate(Activity.java:5255) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2213) 
10-10 10:07:46.502: E/AndroidRuntime(8971):  ... 11 more 

CriminalListActivitie:

package com.example.csi_week1; 

import android.support.v7.app.ActionBarActivity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ListView; 

public class CriminalListActivitie extends ActionBarActivity { 


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

     ListView listview = (ListView) findViewById(R.id.listViewCriminals); 

     listview.setAdapter(new CriminalProvider(this.getApplicationContext())); 

     listview.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       CriminalProvider provider = (CriminalProvider)parent.getAdapter(); 
       Criminal criminal = provider.GetCriminal(position); 
       Intent i = new Intent(); 
       i.setClass(getBaseContext(), MainActivity.class); 
       i.putExtra("criminal", criminal); 
       startActivity(i); 
      }}); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.criminal_list_activitie, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     if (id == R.id.action_settings) { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 


} 

CriminalAdapter:

package com.example.csi_week1; 

    import java.util.ArrayList; 
    import java.util.Collections; 
    import java.util.List; 
    import java.util.Random; 
    import android.annotation.SuppressLint; 
    import android.content.Context; 
    import android.location.Location; 
    import android.view.LayoutInflater; 
    import android.view.View; 
    import android.view.ViewGroup; 
    import android.widget.ArrayAdapter; 
    import android.widget.ImageView; 
    import android.widget.TextView; 

    /** 
    * This class can be used to generate random criminals, and retrieve them based on their index. 
    * @author Michael 
    * 
    */ 
    @SuppressLint("UseSparseArrays") 
    public class CriminalProvider extends ArrayAdapter<Criminal>{ 

     /** 
     * This list contains the generated criminals. 
     * Notice the static. This means that all CriminalProvider classes share the same list. 
     */ 
     private static List<Criminal> criminalList; 
     /** 
     * This context can be used to acquire the resources. 
     */ 
     private Context context; 

     /** 
     * Constructor of the CriminalProvider. 
     * @param context The context (i.e. the activity) that is using this provider. 
     */ 
     public CriminalProvider(Context context) 
     { 
      super(context, R.layout.activitie_activity_criminal_list, criminalList); 
      this.context = context; 

      if(criminalList == null) 
      { 
       criminalList = new ArrayList<Criminal>(); 
       fillCriminalList(); 
      } 
     } 

     /** 
     * Get the list with all stored criminals 
     * @return the list with criminals 
     */ 
     public List<Criminal> GetCriminals() 
     { 
      return criminalList; 
     } 

     /** 
     * Get a specific criminal 
     * @param the index of the criminal in the list 
     * @return the criminal 
     */ 
     public Criminal GetCriminal(int index) { 
      if(index >= criminalList.size()) return null; 

      return criminalList.get(index); 
     } 

     /** 
     * Creates a criminals. 
     */ 
     private void fillCriminalList() 
     { 
      //Load criminal and crime information from resource xml files (see res/values folder): 
      String[] criminalNames = context.getResources().getStringArray(R.array.criminalNames); 
      String[] criminalDetails = context.getResources().getStringArray(R.array.criminalDetails); 

      int[] drawableIds = new int[] { R.drawable.mugshot1, R.drawable.mugshot2, 
        R.drawable.mugshot3, R.drawable.mugshot4, R.drawable.mugshot5 }; 

      String[] crimeNames = context.getResources().getStringArray(R.array.crimeNames); 
      String[] crimeDetails = context.getResources().getStringArray(R.array.crimeDetails); 

      for(int criminalIndex = 0; criminalIndex < criminalNames.length; criminalIndex++) 
      { 
       Criminal someCriminal = new Criminal(); 

       someCriminal.name = criminalNames[criminalIndex]; 
       someCriminal.description = criminalDetails[criminalIndex]; 

       int drawableId = drawableIds[criminalIndex]; 
       someCriminal.mugshot = context.getResources().getDrawable(drawableId); 

       Random r = new Random(); 
       someCriminal.gender = r.nextBoolean() ? "Male":"Female"; 
       someCriminal.age = 10 + r.nextInt(100); 

       someCriminal.lastKnownLocation = new Location(""); 
       someCriminal.lastKnownLocation.setLatitude(-180.0 + r.nextDouble() * 180.0); 
       someCriminal.lastKnownLocation.setLongitude(-180.0 + r.nextDouble() * 180.0); 

       someCriminal.crimes = new ArrayList<Crime>(); 
       int maxNumberOfCrimes = context.getResources().getStringArray(R.array.crimeNames).length; 
       int numCrimes = 1 + r.nextInt(maxNumberOfCrimes); 
       for (int c = 0 ; c < numCrimes; c++) 
       { 
        Crime crime = createRandomCrime(crimeNames, crimeDetails); 
        someCriminal.crimes.add(crime); 
       } 

       criminalList.add(someCriminal); 
      } 

      Collections.shuffle(criminalList); 
     } 

     /** 
     * Creates a random crime. The name and description are picked from the resource files. 
     * @return The random crime. 
     */ 
     private Crime createRandomCrime(String [] crimeNames, String[] crimeDetails) 
     { 
      Crime randomCrime = new Crime(); 
      Random r = new Random(); 

      int randomInt = r.nextInt(crimeNames.length); 
      randomCrime.name = crimeNames[randomInt]; 

      randomInt = r.nextInt(crimeDetails.length); 
      randomCrime.description = crimeDetails[randomInt]; 

      randomCrime.bountyInDollars = r.nextInt(100000); 

      return randomCrime; 
     } 
     @Override 
     public View getView(int position, View convertView, ViewGroup parent) 
     { 
      LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View criminalView = inflater.inflate(R.layout.item_criminal_list, null); 
      ImageView mug = (ImageView)criminalView.findViewById(R.id.imageView1); 
      mug.setImageDrawable(criminalList.get(position).mugshot); 

      TextView name = (TextView)criminalView.findViewById(R.id.textView1); 
      name.setText(criminalList.get(position).name); 

      TextView bountyTotal = (TextView)criminalView.findViewById(R.id.textView2); 
      bountyTotal.setText(criminalList.get(position).getBountyInDollars()); 

      return criminalView; 
     } 

    } 

回答

0

在你CriminalProvider構造你提供初始化criminalListnull)到超ArrayAdapter構造函數。您只在將空引用傳遞給超級構造函數後才初始化列表。

移動

criminalList = new ArrayList<Criminal>() 

的成員變量初始化部分:

private static List<Criminal> criminalList = new ArrayList<Criminal>(); 

static是一個代碼味道在這裏,但如果你堅持使用它,你可以如檢查列表的size()以查看是否需要將其填充到適配器構造函數中。