【问题标题】:Pebble Menu Layer CrashPebble 菜单层崩溃
【发布时间】:2016-07-07 12:48:11
【问题描述】:

我一直在为原始 pebble 设计一个个人新闻提要应用程序,它在菜单层中显示新闻内容。我有两个 C 文件,一个包含一个显示加载图像的窗口,并处理手机上的 js 和我的手表应用程序之间的数据传输。数据被保存到文件之间共享的一些外部变量中,但在我下面展示的示例中无关紧要(我相信所有这些都可以正常工作)。

当满足某些条件时,我在函数内的主 .c 文件中调用 news_list_window_init()。现在我只是想显示一个带有可滚动菜单的窗口来测试我的菜单看起来是否可以接受。我遇到的问题是当我尝试滚动时我的应用程序崩溃了。出现窗口,我的所有菜单项都在那里,但是当我滚动应用程序时,应用程序存在:

ault_handling.c:78> App fault! {f5ec8c0d-9f21-471a-9a5c-c83320f7477d} PC: 0x800fd5b LR: ???
Program Counter (PC)    : 0x800fd5b  ???
Link Register (LR)      : ???        ???

我已经在下面独立测试了我的 .c 文件,在这里我只使用此代码创建了一个新项目,注释掉不相关的 news_list.hexterns.h 头文件,并在底部的 main 函数中注释的文件。这工作正常,我的菜单滚动,没有崩溃,一切看起来都很好。

我看不出问题出在我的主文件中,因为我在其中调用的唯一一个包含在该文件中的函数是news_list_window_init(),而且菜单确实显示正确。我什至可以使用返回按钮正确关闭应用程序。但是尝试滚动会使应用程序崩溃。我对可能导致此错误的原因感到不知所措。有人有什么建议吗?谢谢!

这是相关的.c文件:

// news_list.c
#include "pebble.h"
#include "news_list.h"
#include "externs.h"

#define NUM_MENU_SECTIONS 1

static Window *news_list_window;
static MenuLayer *menu_layer;

static uint16_t menu_get_num_sections_callback(MenuLayer *menu_layer, void *data) {
  return NUM_MENU_SECTIONS;
}

static uint16_t menu_get_num_rows_callback(MenuLayer *menu_layer, uint16_t section_index, void *data) {
  return str_count; // Variable story count
}

static int16_t menu_get_header_height_callback(MenuLayer *menu_layer, uint16_t section_index, void *data) {
  return MENU_CELL_BASIC_HEADER_HEIGHT;
}

static void menu_draw_header_callback(GContext* ctx, const Layer *cell_layer, uint16_t section_index, void *data) {
  menu_cell_basic_header_draw(ctx, cell_layer, "Header");
}

static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuIndex *cell_index, void *data) {
  menu_cell_basic_draw(ctx, cell_layer, "Menu Item", NULL, NULL);
}

static void menu_select_callback(MenuLayer *menu_layer, MenuIndex *cell_index, void *data) {
  // Currently Empty
}

int16_t menu_get_cell_height_callback(struct MenuLayer *menu_layer, MenuIndex *cell_index, void *callback_context)
{
    return 40;
}

static void news_list_window_load(Window *window) {
  // Now we prepare to initialize the menu layer
  Layer *window_layer = window_get_root_layer(window);
  GRect bounds = layer_get_frame(window_layer);

  // Create the menu layer
  menu_layer = menu_layer_create(bounds);
  menu_layer_set_callbacks(menu_layer, NULL, (MenuLayerCallbacks){
    .get_num_sections = menu_get_num_sections_callback,
    .get_num_rows = menu_get_num_rows_callback,
    .get_header_height = menu_get_header_height_callback,
    .draw_header = menu_draw_header_callback,
    .draw_row = menu_draw_row_callback,
    .select_click = menu_select_callback,
    .get_cell_height = menu_get_cell_height_callback,
  });

  // Bind the menu layer's click config provider to the window for interactivity
  menu_layer_set_click_config_onto_window(menu_layer, window);

  layer_add_child(window_layer, menu_layer_get_layer(menu_layer));
}

static void news_list_window_unload(Window *window) {
  // Destroy the menu layer
  menu_layer_destroy(menu_layer);
}

void news_list_window_init() {
  news_list_window = window_create();
  window_set_window_handlers(news_list_window, (WindowHandlers) {
    .load = news_list_window_load,
    .unload = news_list_window_unload,
  });
  window_stack_push(news_list_window, true);
}

void news_list_window_deinit() {
  window_destroy(news_list_window);
}

// int main(void) {
//   news_list_window_init();
//   app_event_loop();
//   news_list_window_deinit();
// }

这是相关的.h文件:

// news_list.h
#ifndef NEWS_LIST_H
#define NEWS_LIST_H

// Public Function list
void news_list_window_init(void);
void news_list_window_deinit(void);

#endif

【问题讨论】:

    标签: c pebble-watch pebble-sdk


    【解决方案1】:

    当我的内存非常低时,或者我以某种方式破坏了内存时,就会发生这种情况。

    我建议检查所有返回值是否为 NULL,如果是(menu_layer_create、malloc 等),则进行日志记录和保释。

    另外,试试 logging 你有多少 free memory - 如果你正在处理原始的 Pebble,并为 communication 分配大内存缓冲区,你很快就会耗尽内存。

    最后,遍历所有分配和使用内存的代码,以绝对确保您不会意外写入超出数组末尾,或将分配在堆栈上的值传递给 pebble 调用。我喜欢使用 calloc 而不是 malloc 来确保我认为我在 malloc 的结构中没有价值。

    我以前来过这里 - 这并不容易,但可能与您的 UI 代码完全无关 - 崩溃只是一个症状。如果一切都失败了,可以将完整的代码发布到 github 中,以便我们查看完整的应用程序......

    达米安

    【讨论】:

    • 这绝对是内存问题。我试图从我的 javascript 应用程序向我的手表应用程序发送一个大数据数组,所以我用一个非常大的缓冲区调用了 app_message_open,它占用了我所有的内存。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多