Java 中的 CustomListAdapter 和 kotlin 中的 MainActivity 在运行时出错

CustomListAdapter in Java and MainActivity in kotlin which is getting error on runtime

我在 Java 中创建了一个 CustomListAdapter,在 kotlin 中创建了 MainActivity。按照下面的方式获取错误它在 运行 应用程序即运行时显示错误。运行时错误是空指针异常。但我没有收到此错误如何解决此错误。请帮助解决这个问题。

错误:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.android.volley.toolbox.ImageLoader novumlogic.payment.AppController.getImageLoader()' on a null object reference
        at novumlogic.payment.adater.CustomListAdapter.<init>(CustomListAdapter.java:24)
        at novumlogic.payment.MainActivity.onCreate(MainActivity.kt:55)
        at android.app.Activity.performCreate(Activity.java:6672)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2612)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6123) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
02-15 20:03:12.342 2997-14890/? E/ActivityManager: Sending non-protected broadcast com.motorola.motocare.INTENT_TRIGGER from system 4467:com.motorola.process.system/1000 pkg com.motorola.motgeofencesvc
    java.lang.Throwable
        at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:18226)
        at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:18826)
        at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:512)
        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2906)
        at android.os.Binder.execTransact(Binder.java:565)

CustomListAdapter.java

public class CustomListAdapter extends BaseAdapter {
    private Activity activity;
    private LayoutInflater inflater;
    private List<Movie> movieItems;
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();

    public CustomListAdapter(Activity activity, List<Movie> movieItems) {
        this.activity = activity;
        this.movieItems = movieItems;
    }

    @Override
    public int getCount() {
        return movieItems.size();
    }

    @Override
    public Object getItem(int location) {
        return movieItems.get(location);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (inflater == null)
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.list_row, null);

        if (imageLoader == null)
            imageLoader = AppController.getInstance().getImageLoader();
        NetworkImageView thumbNail = (NetworkImageView) convertView
                .findViewById(R.id.thumbnail);
        TextView title = (TextView) convertView.findViewById(R.id.title);
        TextView rating = (TextView) convertView.findViewById(R.id.rating);
        TextView genre = (TextView) convertView.findViewById(R.id.genre);
        TextView year = (TextView) convertView.findViewById(R.id.releaseYear);

        // getting movie data for the row
        Movie m = movieItems.get(position);

        // thumbnail image
        thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);

        // title
        title.setText(m.getTitle());

        // rating
        rating.setText("Rating: " + String.valueOf(m.getRating()));

        // genre
        String genreStr = "";
        for (String str : m.getGenre()) {
            genreStr += str + ", ";
        }
        genreStr = genreStr.length() > 0 ? genreStr.substring(0,
                genreStr.length() - 2) : genreStr;
        genre.setText(genreStr);

        // release year
        year.setText(String.valueOf(m.getYear()));

        return convertView;
    }

}

MainActivity.kt

class MainActivity : AppCompatActivity() {
    var selectedFragment: Fragment? = null


    /// Image And text Volley

    // Log tag
    private val TAG = MainActivity::class.java.simpleName
    //private var CustomListAdapter adapter
    // Movies json url
    private val url = "https://api.androidhive.info/json/movies.json"
    private var pDialog: ProgressDialog? = null
    private val movieList = ArrayList<Movie>()
    private var listView: ListView? = null
    private var adapter: CustomListAdapter? = null

    /////////////   Image And text Volley END

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ///////////// Image And TExt Volley start


        listView = findViewById(R.id.list) as ListView
        adapter = CustomListAdapter(this, movieList)
        listView!!.setAdapter(adapter)

        pDialog = ProgressDialog(this)
        // Showing progress dialog before making http request
        pDialog!!.setMessage("Loading...")
        pDialog!!.show()

        // changing action bar color
        actionBar!!.setBackgroundDrawable(
                ColorDrawable(Color.parseColor("#1b1b1b")))

        // Creating volley request obj
        val movieReq = JsonArrayRequest(url,
                Response.Listener { response ->
                    Log.d(TAG, response.toString())
                    hidePDialog()

                    // Parsing json
                    for (i in 0 until response.length()) {
                        try {

                            val obj = response.getJSONObject(i)
                            val movie = Movie()
                            movie.title = obj.getString("title")
                            movie.thumbnailUrl = obj.getString("image")
                            movie.rating = (obj.get("rating") as Number)
                                    .toDouble()
                            movie.year = obj.getInt("releaseYear")

                            // Genre is json array
                            val genreArry = obj.getJSONArray("genre")
                            val genre = ArrayList<String>()
                            for (j in 0 until genreArry.length()) {
                                genre.add(genreArry.get(j) as String)
                            }
                            movie.genre = genre

                            // adding movie to movies array
                            movieList.add(movie)

                        } catch (e: JSONException) {
                            e.printStackTrace()
                        }

                    }

                    // notifying list adapter about data changes
                    // so that it renders the list view with updated data
                    adapter!!.notifyDataSetChanged()
                }, Response.ErrorListener { error ->
            VolleyLog.d(TAG, "Error: " + error.message)
            hidePDialog()
        })

        // Adding request to request queue
        AppController.getInstance()?.addToRequestQueue(movieReq)

}

AppController.Kt

val TAG = AppController::class.java.simpleName
//private var mRequestQueue: RequestQueue? = null
//private var mImageLoader: ImageLoader? = null
var mRequestQueue: RequestQueue? = null
var mImageLoader: ImageLoader? = null

var mInstance: AppController? = null

class AppController : Application() {

    var mRequestQueue: RequestQueue? = null
    var mImageLoader: ImageLoader? = null
    override fun onCreate() {


        super.onCreate()
        Fresco.initialize(this)
    }




   // @Synchronized
     companion object{
    @JvmStatic
    fun getInstance(): AppController? {
        return mInstance
    }}

    fun getRequestQueue(): RequestQueue? {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(applicationContext)
        }

        return mRequestQueue
    }

    fun getImageLoader(): ImageLoader {
        getRequestQueue()
        if (mImageLoader == null) {
            mImageLoader = ImageLoader(this.mRequestQueue,
                    LruBitmapCache())
        }
        return this.mImageLoader!!
    }

    fun <T> addToRequestQueue(req: Request<T>, tag: String) {
        // set the default tag if tag is empty
        req.tag = if (TextUtils.isEmpty(tag)) TAG else tag
        getRequestQueue()!!.add(req)
    }

    fun <T> addToRequestQueue(req: Request<T>) {
        req.tag = TAG
        getRequestQueue()!!.add(req)
    }

    fun cancelPendingRequests(tag: Any) {
        if (mRequestQueue != null) {
            mRequestQueue!!.cancelAll(tag)
        }
    }
}

用这个替换 AppController 并检查它是否有效。

val TAG = AppController::class.java.simpleName
//private var mRequestQueue: RequestQueue? = null
//private var mImageLoader: ImageLoader? = null
var mRequestQueue: RequestQueue? = null
var mImageLoader: ImageLoader? = null

var mInstance: AppController? = null

class AppController : Application() {

    var mRequestQueue: RequestQueue? = null
    var mImageLoader: ImageLoader? = null
    override fun onCreate() {
        super.onCreate()
        mInstance = this
        Fresco.initialize(this)
    }  

   // @Synchronized
     companion object{
    @JvmStatic
    fun getInstance(): AppController? {
        return mInstance
    }}

    fun getRequestQueue(): RequestQueue? {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(applicationContext)
        }

        return mRequestQueue
    }

    fun getImageLoader(): ImageLoader {
        getRequestQueue()
        if (mImageLoader == null) {
            mImageLoader = ImageLoader(this.mRequestQueue,
                    LruBitmapCache())
        }
        return this.mImageLoader!!
    }

    fun <T> addToRequestQueue(req: Request<T>, tag: String) {
        // set the default tag if tag is empty
        req.tag = if (TextUtils.isEmpty(tag)) TAG else tag
        getRequestQueue()!!.add(req)
    }

    fun <T> addToRequestQueue(req: Request<T>) {
        req.tag = TAG
        getRequestQueue()!!.add(req)
    }

    fun cancelPendingRequests(tag: Any) {
        if (mRequestQueue != null) {
            mRequestQueue!!.cancelAll(tag)
        }
    }
}