【问题标题】:How to make a blackberry application start , by code?如何通过代码启动黑莓应用程序?
【发布时间】:2013-04-09 03:05:00
【问题描述】:

我有一个监听推送消息的后台函数。我需要处理推力。我创建了在推送到达时执行任何操作的函数,它运行良好。例如,当推送到达时,我会增加一个数字等。

但是,当用户按下 ok 进行推送时,实际启动应用程序的代码是什么?

我只需要让应用程序正常启动,就像用户刚刚按下应用程序的图标一样。

I am using OS < 7.X

【问题讨论】:

    标签: blackberry java-me push-notification blackberry-jde


    【解决方案1】:

    一个典型的模式是构建一个有两个入口点的应用程序。也就是说,它可以以两种不同的方式启动。一种方法是普通的UiApplication。这是标准的 BlackBerry 应用程序,只需按下主屏幕图标即可启动。

    另一种方法是定义一个后台服务,处理推送通知,并在设备启动时由操作系统启动。

    您将通过在应用的 BlackBerry_App_Descriptor.xml 文件中添加备用入口点来定义后台/推送入口点。确保选中启动时自动运行不显示应用程序图标...。除了 UiApplication 的正常入口点之外,您的应用程序描述符 xml 文件应该包含类似这样的内容:

      <AlternateEntryPoints>
        <AlternateEntryPoint Title="PushService" MainMIDletName="" 
                             ArgumentsForMain="-push" HomeScreenPosition="0"
                             StartupTier="7" IsSystemModule="true" 
                             IsAutostartup="true" hasTitleResource="false" 
                             TitleResourceBundleKey="" TitleResourceBundleName="" 
                             TitleResourceBundleClassName="" TitleResourceBundleRelativePath="">
          <Icons/>
          <KeywordResources KeywordResourceBundleName="" KeywordResourceBundleRelativePath="" KeywordResourceBundleClassName="" KeywordResourceBundleKey=""/>
        </AlternateEntryPoint>
      </AlternateEntryPoints>
    

    然后,你将有一个这样的主程序:

    public class MyApp extends UiApplication
    
        public static void main(String[] args) {
           if (args.length > 0 && args[0].equals("-push")) {
              // this is the push service
              PushAgent pa = new PushAgent();
              pa.enterEventDispatcher();
           } else {
              // UiApplication
              MyApp app = new MyApp();
              app.enterEventDispatcher();
           }
        }
    }
    

    其中PushAgentextends Application 的类,而不是UiApplication

    然后,当您的推送代理收到通知并且您决定要显示 UI 时,请使用以下内容:

    ApplicationDescriptor ad = ApplicationDescriptor.currentApplicationDescriptor();
    // String[] used for command line args, but we don't pass any to the UI app
    ApplicationDescriptor ui = new ApplicationDescriptor(ad, new String[] { });
    ApplicationManager.getApplicationManager().runApplication(ui);
    

    【讨论】:

    • 什么是 ApplicationDescriptor,为什么我会出错?即使我输入 .xml 名称也会出错。
    • @donparalias,你说的是ApplicationDescriptor class,还是BlackBerry_App_Descriptor.xml file?这些是不同的东西。我的答案中的最后 4 行是用于启动 UI 应用程序的 Java 代码。 BlackBerry_App_Descriptor.xml 是您的应用程序的各种配置文件。这通常由 BlackBerry Eclipse 插件在您创建新项目时生成。它通常位于项目的根目录中,在硬盘上。
    • 我的意思是最后 4 行。好的,导致我没有导入某些类的错误,并且没有尝试使用。但即使现在我这样做了,它也不会启动我的应用程序。
    • @donparalias,你的main(String[]) 方法是按照我上面的方式编码的吗?它需要。该代码依赖于在同一个应用程序中有两个单独的入口点。相同的 main(String[]) 方法必须同时处理后台启动和 UI 应用程序启动。后台(推送)服务将通过传递 -push 作为参数来运行,如果没有参数,则 UI 应用程序将启动。
    【解决方案2】:

    试试这个 - 当您单击确定按钮时,使用以下代码运行您的 ui 应用程序。

    public void dialogClosed(Dialog dialog, int choice) {
          switch (choice) {
              case Dialog.OK: 
                  try {
    
                      ApplicationDescriptor[] appDescriptors =CodeModuleManager.getApplicationDescriptors(CodeModuleManager.getModuleHandle("BlackBerryCity"));    //here BlackBerryCity is the COD module Name
                      ApplicationDescriptor appDescriptor = new ApplicationDescriptor(appDescriptors[0], new String[] {"BlackBerryCity"});
                      ApplicationManager.getApplicationManager().runApplication(appDescriptor);
    
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
    
                  break;
              case Dialog.CANCEL:
    
                  break;
              default:
                  break;
           }
       }
    

    【讨论】:

    • 看起来您可能已经掌握了这种通用技术from this question/answer,但如果main(String[]) 函数期待"cod module name of your application",您只需将"cod module name of your application" 作为字符串参数传递。在我链接到的问题中,它是,但总的来说,我猜大多数人没有这样编码。当然,它只需要保持一致即可。
    • 您可以简单地从 currentApplicationDescriptor 属性中创建一个新的 ApplicationDescriptor,而不是从模块中获取应用程序描述符。我假设正在侦听推送的代码与要启动的应用程序位于同一模块中。
    【解决方案3】:
    class EntryPointForApplication extends UiApplication {
    
        private static EntryPointForApplication theApp;
    
        public EntryPointForApplication() { 
            GUIApplication scr = new GUIApplication(); 
            pushScreen(scr);         
        } 
    
    }
    

    也请阅读How to setup alternate entry point in Blackberry application?

    【讨论】:

    • 静态成员有什么用?
    • @adwiv 如果您看到我分享的链接,您将了解它如何进一步使用(在 main 方法中)
    • 我认为它在共享链接中的使用方式完全没用,并且基于对 BB 流程如何工作的错误理解。 BB 中的静态对象仅限于进程——它们不会在不同的应用程序实例之间共享。 main 方法对每个应用实例只运行一次,因此检查 theApp 是否为 null 将始终成功。
    • 我读到了,我说那里的描述是错误的 :-) 无论您是否使用该静态变量,在正常情况下您永远不会获得多个实例。自己试试。并且在异常情况下,静态变量不会阻止新实例的创建。
    • 他是对的。静态变量将被创建两次,并具有 2 个独立且不相关的值。即使您使用备用入口点,静态变量也不会在应用程序的两个实例之间共享。这段代码只会误导任何试图在不知情的情况下使用它的人
    【解决方案4】:

    为了完整起见,这里列出了您可以用来启动应用程序的所有选项:

    我假设您已经有多个入口点 - 一个用于后台侦听器,一个用于 UI 应用程序。还假设您没有为 UI 应用程序传递任何应用程序参数。 (有关如何执行此操作的完整说明,请参阅 Nate 的回答。)

    1. 使用runApplication()方法:

      ApplicationDescriptor ad = ApplicationDescriptor.currentApplicationDescriptor();
      // String[] used for command line args, but we don't pass any to the UI app
      ApplicationDescriptor ui = new ApplicationDescriptor(ad, new String[] { });
      //Launch the application and ask it to come in foreground
      ApplicationManager.getApplicationManager().runApplication(ui, true);
      
    2. 使用launch()方法:

      String modulename = "mymodule";
      ApplicationManager.launch(modulename);
      
    3. 使用launchApplication() 方法:

      String modulename = "mymodule";
      ApplicationManager.launchApplication(modulename);
      

    需要注意的一点是,如果您的 UI 应用程序已经打开,所有这些方法都会简单地将其带到前台,无论它处于何种状态。如果您需要单击按钮来打开应用程序的新实例,则必须传递一些随机参数作为应用程序参数,然后在 main 方法中忽略它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多