论坛首页 移动开发技术论坛

很怪异的现象

浏览 10243 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-07-20  
我们的程序在真机上(现在测了2个手机,索爱一款,另外一款是国产的)会出现启动问题,我跟踪问题到,最后打log发现时因为以下代码:
m_display = Display.getDisplay(midlet);
m_display.setCurrent(m_mainCanvas);

m_display.getCurrent().getWidth()
m_display.getCurrent().getHeight()

在下面一段就会出问题,m_display.getCurrent()取得的是null。。但是m_display.setCurrent(m_mainCanvas);发生在先,按理说不会出现getCurrent为null的问题啊。。midlet、m_mainCanvas(Canvas对象)和m_display都是正常的(至少不是null)。
我查看了j2me相关的doc,doc上说明的原因是在setCurrent之前getCurrent就会返回null。

由于这个问题不能在模拟器上复现,只能一遍一遍的修改然后上真机看log,非常麻烦。。不知道坛子里搞j2me的朋友有没有碰到过这种情况的,或者有什么建议?
   发表时间:2010-07-21  
补充的一点是,如果我在getCurrent之前Thread.sleep(1000),那么真机上就正常了。
可是加这延迟按理说是不对的,但是偏偏能解决问题。
public final class Ambig extends MIDlet
{

	private static Ambig m_midlet;
	private DisplayModule m_displayModule;
	private static PageContainer m_pageContainer;
	private boolean m_initialized;

	/** 构造方法,仅仅初始化Module表 */
	public Ambig()
	{
		m_midlet = this;
		//在DisplayModule构造器里面对显示模块进行启动,显示模块生成Canvas对象main_canvas,
		//并调用setCurrent(main_canvas)
		m_displayModule = new DisplayModule(this);
		//module本身是一个线程,但是线程run方法是空实现
		m_displayModule.start();
	}

	/** 初始化各Module。 */
	private void initModules()
	{
		/*try
		{
			Thread.sleep(1000);
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
		}*/

		m_pageContainer = new PageContainer(m_displayModule);

		//do other things ...
	}

	protected void startApp() throws MIDletStateChangeException
	{
		try
		{
			if (!m_initialized)
			{
				initModules();

				m_initialized = true;
			}
		}
		catch (Exception e)
		{
		}
	}

	//
	public static int getScreenHeight()
	{
		return Display.getDisplay(m_midlet).getCurrent().getHeight();
	}

	public static int getScreenWidth()
	{
		return Display.getDisplay(m_midlet).getCurrent().getWidth();
	}

	protected void pauseApp()
	{
	}
	protected void destroyApp(boolean arg0) throws MIDletStateChangeException
	{
	}
}

//PageContainer的构造函数,这里的getScreenWidth就报空指针,Display.getDisplay(m_midlet)不是null,但是getCurrent()却得到null,
//但是在DisplayModule的构造器里面已经调用了Display.getDisplay(m_midlet).setCurrent(main_canvas),main_canvas也不是null
//如果在initModules里进行线程延迟,ok没问题;但是去掉后就在PageContainer的super里就报空指针
public PageContainer(DisplayModule m_dis)
{
	super(null, 0, 0, Ambig.getScreenWidth(), Ambig.getScreenHeight());

	//do other things
}


0 请登录后投票
   发表时间:2010-07-21  
莫非是和getScreenHeight(),getScreenWidth()这两个方法是静态有关?
0 请登录后投票
   发表时间:2010-07-21  
这说明setCurrent方法是异步的
0 请登录后投票
   发表时间:2010-07-21  
chroya 写道
这说明setCurrent方法是异步的


的确,setCurrent方法是异步的,不仅仅是它,Display类内部几乎对外公布的api都实现了同步。

找了一下午,感觉问题可能在我们的重绘线程,如果该线程在setcurrent前调用,则真机上异常,之后则没有事。具体原因还没有查清除。
0 请登录后投票
   发表时间:2010-07-22  

    /** 构造方法,仅仅初始化Module表 */   
    public Ambig()   
    {   
        m_midlet = this;   
        //在DisplayModule构造器里面对显示模块进行启动,显示模块生成Canvas对象main_canvas,   
        //并调用setCurrent(main_canvas)   
        m_displayModule = new DisplayModule(this);   
        //module本身是一个线程,但是线程run方法是空实现   
        m_displayModule.start();   
    }   

当线程启动时,构造可能还没有构造完成,也就是this并没有完成全部初始化工作,调用m_midlet相关的东西就可能有问题。
0 请登录后投票
   发表时间:2010-07-23  
Teok 写道
chroya 写道
这说明setCurrent方法是异步的


的确,setCurrent方法是异步的,不仅仅是它,Display类内部几乎对外公布的api都实现了同步。

找了一下午,感觉问题可能在我们的重绘线程,如果该线程在setcurrent前调用,则真机上异常,之后则没有事。具体原因还没有查清除。

so you know the reason, it's 异步的, when you call getCurrent(), setCurrent() is very possible not finished, that's why sleep(1000) can fix it.
0 请登录后投票
   发表时间:2010-07-23   最后修改:2010-07-23
这必须是异步的,就像网络连接或者创建摄像头一样是异步并且需要单独放在一个run里进行的。

你必须确定对象创建完毕后,才可以进行下一步关于这个对象的操作,所以你要单独开启一个线程进行创建对象操作或者是单独开启一个等待对象创建完毕的线程(当然这个线程里要有一个while方法做监听)。

重绘问题,应该就是线程假死不重绘的问题,就像网络连接一样,整体都在一起的话,页面肯定假死。
0 请登录后投票
   发表时间:2010-07-23  
zovikoo 写道
这必须是异步的,就像网络连接或者创建摄像头一样是异步并且需要单独放在一个run里进行的。

你必须确定对象创建完毕后,才可以进行下一步关于这个对象的操作,所以你要单独开启一个线程进行创建对象操作或者是单独开启一个等待对象创建完毕的线程(当然这个线程里要有一个while方法做监听)。

重绘问题,应该就是线程假死不重绘的问题,就像网络连接一样,整体都在一起的话,页面肯定假死。


大概是这样得原因,不过还不是很确定。。所以我帮构造函数里面启动线程得操作拿出来,放在外面执行,然后就可以了。
0 请登录后投票
   发表时间:2010-08-01  
明白构造函数构造这两个字的意思吗?

m_displayModule.start();
放在initModules()中应该就可以了吧
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics