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)
}
}
}
我在 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)
}
}
}