我是安卓开发的新手。我当前的应用程序在来自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 对象,然后使用它。