Pebble 菜单层崩溃
Pebble Menu Layer Crash
我一直在为原始pebble 设计一个个人新闻提要应用程序,它在菜单层中显示新闻内容。我有两个 C 文件,其中一个包含 window,它显示加载图像并处理 phone 上的 js 和我的手表应用程序之间的数据传输。数据被保存到一些外部变量中,这些变量在文件之间共享,但与我在下面显示的示例中无关(我相信所有这些都工作正常)。
当满足某些条件时,我在函数内的主 .c 文件中调用 news_list_window_init()
。现在我只是想显示一个带有可滚动菜单的 window 来测试我的菜单看起来是否可以接受。我遇到的问题是当我尝试滚动时我的应用程序崩溃了。 window 出现,我所有的菜单项都在那里但是当我滚动时应用程序存在:
ault_handling.c:78> App fault! {f5ec8c0d-9f21-471a-9a5c-c83320f7477d} PC: 0x800fd5b LR: ???
Program Counter (PC) : 0x800fd5b ???
Link Register (LR) : ??? ???
我在下面独立测试了我的 .c 文件,我在其中创建了一个仅包含此代码的新项目,注释掉了不相关的 news_list.h
和 externs.h
头文件,并在文件底部的主要功能。这工作正常,我的菜单滚动并且没有崩溃,一切看起来都很好。
我看不出问题出在我的主文件中,因为我在主文件中调用的唯一函数是 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
当我 运行 内存非常低,或者我以某种方式破坏内存时,我就遇到过这种情况。
我建议检查所有 return 值是否为 NULL,如果它们是 NULL(menu_layer_create、malloc 等),则进行日志记录和保释。
另外,试试logging how much free memory you have - if you are working on an original Pebble, and allocating large memory buffers for communication,你很快就会运行内存不足。
最后,遍历分配和使用内存的所有代码,以绝对确保您没有意外写入数组末尾,或将分配在堆栈上的值传递给 pebble 调用。我喜欢使用 calloc rather than malloc 来确保我认为我在 malloc 结构中没有价值,而我却没有。
我以前来过这里 - 这并不容易,但可能与您的 UI 代码完全无关 - 崩溃只是一个症状。如果所有其他方法都失败了,也许 post github 中的完整代码,以便我们可以查看完整的应用程序...
达米安
我一直在为原始pebble 设计一个个人新闻提要应用程序,它在菜单层中显示新闻内容。我有两个 C 文件,其中一个包含 window,它显示加载图像并处理 phone 上的 js 和我的手表应用程序之间的数据传输。数据被保存到一些外部变量中,这些变量在文件之间共享,但与我在下面显示的示例中无关(我相信所有这些都工作正常)。
当满足某些条件时,我在函数内的主 .c 文件中调用 news_list_window_init()
。现在我只是想显示一个带有可滚动菜单的 window 来测试我的菜单看起来是否可以接受。我遇到的问题是当我尝试滚动时我的应用程序崩溃了。 window 出现,我所有的菜单项都在那里但是当我滚动时应用程序存在:
ault_handling.c:78> App fault! {f5ec8c0d-9f21-471a-9a5c-c83320f7477d} PC: 0x800fd5b LR: ???
Program Counter (PC) : 0x800fd5b ???
Link Register (LR) : ??? ???
我在下面独立测试了我的 .c 文件,我在其中创建了一个仅包含此代码的新项目,注释掉了不相关的 news_list.h
和 externs.h
头文件,并在文件底部的主要功能。这工作正常,我的菜单滚动并且没有崩溃,一切看起来都很好。
我看不出问题出在我的主文件中,因为我在主文件中调用的唯一函数是 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
当我 运行 内存非常低,或者我以某种方式破坏内存时,我就遇到过这种情况。
我建议检查所有 return 值是否为 NULL,如果它们是 NULL(menu_layer_create、malloc 等),则进行日志记录和保释。
另外,试试logging how much free memory you have - if you are working on an original Pebble, and allocating large memory buffers for communication,你很快就会运行内存不足。
最后,遍历分配和使用内存的所有代码,以绝对确保您没有意外写入数组末尾,或将分配在堆栈上的值传递给 pebble 调用。我喜欢使用 calloc rather than malloc 来确保我认为我在 malloc 结构中没有价值,而我却没有。
我以前来过这里 - 这并不容易,但可能与您的 UI 代码完全无关 - 崩溃只是一个症状。如果所有其他方法都失败了,也许 post github 中的完整代码,以便我们可以查看完整的应用程序...
达米安