Profile Image
3
Josephin DoeTyping . .
Profile Image
1
Lary Doeonline
Profile Image
Aliceonline
Profile Image
1
Alia10 min ago
Profile Image
Suzen15 min ago
Profile Image
3
Josephin DoeTyping . .
Profile Image
1
Lary Doeonline
Profile Image
Aliceonline
Profile Image
1
Alia10 min ago
Profile Image
Suzen15 min ago
Profile Image
3
Josephin DoeTyping . .
Profile Image
1
Lary Doeonline
Profile Image
Aliceonline

New Group

New Contact

Profile Image

Josephin Doei am not what happened . .

Profile Image
Lary DoeAvalable
Profile Image
Alicehear using Dasho
A
AliaAvalable
Profile Image
SuzenAvalable
JD
Josephin DoeDon't send me image
Profile Image
Lary Doenot send free msg
Desktop settings

You get latest content at a time when data will updated

Application settings

Automaticaly take backup as par schedule

System settings

Allow to show public user message

Josephin Doe
Profile Image

hello tell me something

about yourself?

8:20 a.m.

Ohh! very nice

8:22 a.m.

Profile Image
Profile Image

can you help me?

8:20 a.m.

白日门app启动时没有WiFi的情况下黑屏的解决办法

文章详情

Image
白日门app启动时没有WiFi的情况下黑屏的解决办法,这个问题出在work\client\frameworks\runtime-src\proj.android\src\org\cocos2dx\lua\AppActivity.java
源代码如下:

/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011      Zynga Inc.
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 ****************************************************************************/
package org.cocos2dx.lua;
import java.util.ArrayList;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.utils.PSNative;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.WindowManager;
public class AppActivity extends Cocos2dxActivity {
    static {
        System.loadLibrary("YvImSdk");
    }
	private static String TAG="Legend";
    static String hostIPAdress = "0.0.0.0";
    static AppActivity instance;
    private BroadcastReceiver batteryLevelRcvr;
    private IntentFilter batteryLevelFilter;
    private BroadcastReceiver myNetReceiver;
    private IntentFilter myNetFilter;
    public static final int NETWORK_2G = 0X01;
	public static final int NETWORK_3G = 0X02;
	public static final int NETWORK_4G = 0X03;
	public static final int NETWORK_WIFI = 0X04;
	public static final int NETWORK_OTHER = 0X05;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	try {
		startActivity(new Intent(this, SplashActivity.class));
	} catch (Exception e) {
		//PlatformSDK.splashSucc=true;
	}
        super.onCreate(savedInstanceState);
        instance=this;
        PSNative.init(this);
        setKeepScreenOn(true);
        int netstate=getNewWorkState();
        if(netstate>>= 8) & 0xFF) + "." + ((ip >>>= 8) & 0xFF) + "." + ((ip >>>= 8) & 0xFF));
    }
    public static String getLocalIpAddress() {
        return hostIPAdress;
    }
    @Override
	protected void onStop()
	{
		super.onStop();
	}
	@Override
	protected void onResume() {
		super.onResume();
	}
	@Override
	protected void onDestroy() {
		super.onDestroy();
//		com.yunva.im.sdk.lib.YvLoginInit.release();
		if (batteryLevelRcvr!=null) {
			unregisterReceiver(batteryLevelRcvr);
		}
		if(myNetReceiver!=null){
			unregisterReceiver(myNetReceiver);
		}
		//YvVoiceSDK.removeYvVoiceListener();
	}
	private void monitorBatteryState() {
		batteryLevelRcvr = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				int rawlevel = intent.getIntExtra("level", -1);
				int scale = intent.getIntExtra("scale", -1);
				LuaJavaBridge.pushPlatformFunc("onBattery" + "|" + rawlevel + "|" + scale);
			}
		};
		batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
		registerReceiver(batteryLevelRcvr, batteryLevelFilter);
	}
	private void monitorNetworkState() {
		myNetReceiver = new BroadcastReceiver() {
			 @Override
			 public void onReceive(Context context, Intent intent) {
				 String action = intent.getAction();
			     if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
			    	int netType=getNewWorkState();
				    LuaJavaBridge.pushPlatformFunc("onNetwork" + "|" + netType);
			     }
			 }
		};
		myNetFilter = new IntentFilter();
		myNetFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
		registerReceiver(myNetReceiver, myNetFilter);
	}
	private int getNewWorkState()
	{
		 ConnectivityManager mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    	 NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
    	 int netType = -1;
    	 if (networkInfo != null && networkInfo.isConnected())
    	    {
    	        if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI)
    	        {
    	        	//"WIFI"
    	        	netType=NETWORK_WIFI;
    	        }
    	        else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE)
    	        {
    	            String _strSubTypeName = networkInfo.getSubtypeName();
    	            Log.e("cocos2d-x", "Network getSubtypeName : " + _strSubTypeName);
    	            // TD-SCDMA   networkType is 17
    	            int networkType = networkInfo.getSubtype();
    	            switch (networkType) {
    	                case TelephonyManager.NETWORK_TYPE_GPRS:
    	                case TelephonyManager.NETWORK_TYPE_EDGE:
    	                case TelephonyManager.NETWORK_TYPE_CDMA:
    	                case TelephonyManager.NETWORK_TYPE_1xRTT:
    	                case TelephonyManager.NETWORK_TYPE_IDEN: //api

原因分析:`AlertDialog` 是 Android 提供的一个标准对话框类,用于在用户界面上显示确认、提示等内容。你现在使用的是 `AlertDialog.Builder` 来构建和显示这个对话框。出现问题的原因可能与以下几点有关:

1. **阻塞 UI 线程**:`AlertDialog` 可能在显示时阻塞了 UI 线程,从而导致游戏没有加载。如果弹窗没有关闭,`loadGame()` 可能无法运行。
2. **显示逻辑问题**:如果 `AlertDialog` 出现了问题(如无法正确显示、被阻塞等),可能导致后续的操作(如游戏加载)不能继续。

如何排查 `AlertDialog` 问题

1. **检查是否正确显示**:
– 确保弹窗显示是否符合预期。你可以通过增加日志打印来确认 `AlertDialog` 是否已经成功显示:

Log.d(TAG, "准备显示 AlertDialog");
     builder.show();
     Log.d(TAG, "AlertDialog 已显示");

这样你可以在 Logcat 中看到这些日志,确认是否到达了显示弹窗的逻辑。

2. **确保对话框不阻塞**:
– 确保弹窗的设计不会阻塞主 UI 线程。可以尝试使用 `DialogInterface.OnDismissListener` 来监控弹窗是否正常被关闭:

builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
         @Override
         public void onDismiss(DialogInterface dialog) {
             Log.d(TAG, "AlertDialog 被关闭,检查是否继续加载游戏");
         }
     });

这样可以监控弹窗关闭的时机,并确保之后的逻辑(比如游戏加载)正常执行。

3. **更换弹窗类型**:
– 如果怀疑 `AlertDialog` 出现问题,你可以尝试使用 `Dialog` 或 `Snackbar` 之类的其他 UI 组件,暂时替换掉 `AlertDialog` 看看是否还会有黑屏问题。

4. **检查 UI 阻塞**:
– 确保对话框弹出时不会阻塞后续的游戏逻辑。你可以在 `AlertDialog` 的 `onClick` 方法中直接调用 `loadGame()` 以确保游戏能正确加载。

调试 `AlertDialog`:

else if (netstate != NETWORK_WIFI) {
    Log.d(TAG, "使用流量时提示用户是否继续,准备显示 AlertDialog");

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("提示");
    builder.setMessage("您当前使用流量,是否继续游戏");

    builder.setPositiveButton("继续", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Log.d(TAG, "点击了继续按钮,准备加载游戏...");
            loadGame(); // 调用游戏加载
        }
    });

    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Log.d(TAG, "点击了取消按钮,准备退出...");
            finish();
            System.exit(0);
        }
    });

    builder.setCancelable(false); // 禁止点击对话框外部取消
    builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
        @Override
        public void onDismiss(DialogInterface dialog) {
            Log.d(TAG, "AlertDialog 被关闭");
        }
    });

    builder.show();
    Log.d(TAG, "AlertDialog 已显示");
} else {
    Log.d(TAG, "如果是WiFi,直接加载游戏...");
    loadGame();
}

通过这些日志,你可以在 Logcat 中清晰地看到对话框显示、关闭、按钮点击等的具体时间点,从而定位问题。

解决办法,你可以将 `AlertDialog` 的显示逻辑放入一个新的线程中,以避免阻塞主 UI 线程。不过,直接在子线程中操作 UI 是不允许的,因为 Android 的 UI 操作必须在主线程(也叫 UI 线程)上执行。你可以通过使用 `runOnUiThread()` 方法来保证 UI 操作在主线程中执行。

以下是将 `AlertDialog` 显示逻辑移到新的线程中的修改方式:

修改代码将 `AlertDialog` 移到新线程

else if (netstate != NETWORK_WIFI) {
    Log.d(TAG, "使用流量时提示用户是否继续,启动新线程显示 AlertDialog");

    // 启动一个新线程
    new Thread(new Runnable() {
        @Override
        public void run() {
            // 使用 runOnUiThread 确保 AlertDialog 在主线程中显示
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, "准备显示 AlertDialog");
                    
                    AlertDialog.Builder builder = new AlertDialog.Builder(AppActivity.this);
                    builder.setTitle("提示");
                    builder.setMessage("您当前使用流量,是否继续游戏");

                    builder.setPositiveButton("继续", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Log.d(TAG, "点击了继续按钮,准备加载游戏...");
                            loadGame(); // 调用游戏加载
                        }
                    });

                    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Log.d(TAG, "点击了取消按钮,准备退出...");
                            finish();
                            System.exit(0);
                        }
                    });

                    builder.setCancelable(false); // 禁止点击对话框外部取消
                    builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                            Log.d(TAG, "AlertDialog 被关闭");
                        }
                    });

                    builder.show();
                    Log.d(TAG, "AlertDialog 已显示");
                }
            });
        }
    }).start(); // 启动新线程
} else {
    Log.d(TAG, "如果是WiFi,直接加载游戏...");
    loadGame();
}

说明:

1. **新线程启动**:通过 `new Thread()` 启动一个新的线程,在该线程中执行对 `AlertDialog` 的显示逻辑。
2. **`runOnUiThread()`**:由于 Android 不允许在非主线程操作 UI,因此使用 `runOnUiThread()` 来确保 `AlertDialog` 在主线程上运行。
3. **游戏继续逻辑**:当用户点击“继续”时,通过 `loadGame()` 加载游戏的逻辑依然不受影响。

这样做可以避免弹窗逻辑阻塞游戏主 UI 线程,从而避免黑屏问题,同时弹窗依然可以正常显示。
你可以将该部分逻辑改进为在没有网络时,提示用户设置网络,但不立即退出,而是持续监听网络状态变化。如果用户在设置网络后有网络了,就继续执行后续逻辑,否则在用户点击“确认”后退出。

以下是修改后的代码,将提示逻辑放入线程中,并在后台持续检查网络状态:

if (netstate < 1) {
    Log.d(TAG, "无网络时提示用户设置网络,启动新线程处理...");

    // 启动一个新线程
    new Thread(new Runnable() {
        @Override
        public void run() {
            // 使用 runOnUiThread 确保 AlertDialog 在主线程中显示
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    AlertDialog.Builder builder = new AlertDialog.Builder(AppActivity.this);
                    builder.setTitle("提示");
                    builder.setMessage("您当前无网络,请设置网络连接");

                    builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
                        }
                    });

                    builder.setCancelable(true);
                    builder.show();
                    Log.d(TAG, "AlertDialog 已显示,等待用户操作...");
                }
            });

            // 持续监测网络状态,直到有网络或者用户退出
            while (true) {
                try {
                    // 每隔 2 秒检查一次网络状态
                    Thread.sleep(2000);

                    int currentNetState = getNewWorkState();
                    Log.d(TAG, "当前网络状态 = " + currentNetState);

                    if (currentNetState >= 1) {
                        Log.d(TAG, "检测到网络连接,准备加载游戏...");
                        
                        // 在主线程中加载游戏
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                loadGame();
                            }
                        });
                        
                        // 跳出循环,结束线程
                        break;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}

逻辑解释:

1. **新线程处理逻辑**:使用 `new Thread()` 启动一个新线程,专门处理弹窗提示和网络状态的监测。
2. **`AlertDialog`**:通过 `runOnUiThread()` 显示网络设置的弹窗,提示用户设置网络连接。点击确认按钮后跳转到网络设置界面。
3. **网络监测**:在后台通过 `while` 循环,每 2 秒检查一次当前的网络状态。如果检测到有网络,调用 `loadGame()` 加载游戏,并跳出循环结束线程。
4. **非退出逻辑**:用户不会立即退出游戏,只有在用户设置网络之后,游戏会继续尝试加载。

这种方式确保了即使没有网络时,用户也不会被迫退出,并且在用户设置网络后,应用能够自动恢复正常继续运行。

Tags:

发表评论