Android OnClick and OnclickListner



我是安卓开发的新手。我当前的应用程序在来自XML的onClick事件上崩溃,但它似乎可以很好地与onClickListner一起使用。

公共静态字符串URL_WEB; NsdUtils mNsdUtils;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final NsdUtils mNsdUtils = new NsdUtils(this);
mNsdUtils.initializeNsd();
/*Button button =(Button) findViewById(R.id.btn_discover_networks);
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View view)
{
mNsdUtils.discoverServices();
}
});*/
}
public void onClickDiscover(View view){
mNsdUtils.discoverServices();
}

原木:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.implicitintents, PID: 6397
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5637) 
at android.view.View$PerformClick.run(View.java:22429) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.android.implicitintents.Utils.NsdUtils.discoverServices()' on a null object reference
at com.example.android.implicitintents.MainActivity.onClickDiscoverAura(MainActivity.java:40)
at java.lang.reflect.Method.invoke(Native Method) 
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
at android.view.View.performClick(View.java:5637) 
at android.view.View$PerformClick.run(View.java:22429) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

似乎我错过了一个非常基本的细节。任何帮助都会很棒。

NsdUtils

public class NsdUtils {
Context mContext;
NsdManager mNsdManager;
NsdManager.ResolveListener mResolveListener;
NsdManager.DiscoveryListener mDiscoveryListener;

//To find all the available networks SERVICE_TYPE = "_services._dns-sd._udp"
public static final String SERVICE_TYPE = "_http._tcp";
public static final String TAG = "NsdUtils";
public String mServiceName = "_hap";
NsdServiceInfo mService;
public NsdUtils(Context context) {
mContext = context;
mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
}
public void initializeNsd() {
initializeDiscoveryListener();
initializeResolveListener();
}
public void initializeDiscoveryListener() {
mDiscoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onDiscoveryStarted(String regType) {
Log.d(TAG, "Service discovery started " + regType);
}
@Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service discovery success" + service);
if(!service.getServiceType().equals(SERVICE_TYPE)){
Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
}
else if(service.getServiceName().equals(mServiceName)){
Log.d(TAG, "Same Machine: " + mServiceName);
}
else if(service.getServiceName().contains(mServiceName)){
mNsdManager.resolveService(service, mResolveListener);
}
}
@Override
public void onServiceLost(NsdServiceInfo service) {
Log.e(TAG, "service lost" + service);
if (mService == service) {
mService = null;
}
}
@Override
public void onDiscoveryStopped(String serviceType) {
Log.i(TAG, "Discovery stopped: " + serviceType);
}
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mNsdManager.stopServiceDiscovery(this);
}
@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mNsdManager.stopServiceDiscovery(this);
}
};
}
public void initializeResolveListener() {
mResolveListener = new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.e(TAG, "Resolve failed" + errorCode);
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
Log.e(TAG, "Resolve Succeeded. " + serviceInfo);
if (serviceInfo.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same IP.");
return;
}
mService = serviceInfo;
}
};
}
public void stopDiscovery() {
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
public NsdServiceInfo getChosenServiceInfo() {
return mService;
}
public void discoverServices() {
mNsdManager.discoverServices(
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}
}

.XML

<Button
android:id="@+id/btn_discover_networks"
android:layout_width="match_parent"
android:layout_height="50dp"
android:onClick="onClickDiscover"
android:text="Discover Networks"/>

如果应该从函数外部访问mNsdUtils,为什么不将其设置为成员字段?

MainActivity.onClickDiscover()实现中说mNsdUtils的根本原因是空的。

在方法本身中实现,因为上下文是不同的,引发空指针异常。

给你一个小提示:阅读堆栈跟踪并找到您的源代码(对于您的情况,MainActivity.java(,以从下到上找到第一个错误。

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.android.implicitintents.Utils.NsdUtils.discoverServices()' on a null object reference
at com.example.android.implicitintents.MainActivity.onClickDiscoverAura(MainActivity.java:40)
at java.lang.reflect.Method.invoke(Native Method) 
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
at android.view.View.performClick(View.java:5637) 
at android.view.View$PerformClick.run(View.java:22429) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

这是你需要的。

at com.example.android.implicitintents.MainActivity.onClickDiscoverAura(MainActivity.java:40)

onClick没有错。请阅读您的以下日志:

由:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'void com.example.android.implicitintents.Utils.NsdUtils.discoverServices(('

这意味着在点击中"mNsdUtils"为空。如需更多帮助,请发布您的 NsdUtils 类。

执行以下操作,您的应用不会崩溃:

public void onClickDiscover(View view){
if(mNsdUtils != null)                  //add this line
mNsdUtils.discoverServices();
}

onClickListener 工作正常。您必须全局实例化 NSD 对象,然后使用它。