В настоящее время я разрабатываю пользовательский интерфейс домашней автоматизации, работающий на настенном планшете android (версия 4.2.2), который после пары минут бездействия отображает страницу html "заставки" .
Как вы можете видеть на скриншоте выше, эта «заставка» в основном состоит из следующих функций:
- часы, отображающие текущее время и дату, запускаемые скриптом date_time. js и обновляемые с интервалом в одну секунду;
- изображение в верхнем правом углу, которое показывает текущий статус сигнала тревоги;
- изображение «Touchez l'écran pour quitter le mode veille», которое случайным образом перемещается каждые 3500 миллисекунд .
Оба пункта 2) и 3) выше выполняются другим сценарием, хранящимся в сценарии, называемом "screensaver_run. js". Метод getAlarmDataFromDatabase извлекает данные из моей mysql базы данных.
Теперь о формулировке проблемы: примерно через два часа весь экран зависает (как часы, так и сценарий изменения положения) таким образом, что даже планшет больше не пингуется. Я подозреваю, что происходит утечка памяти, но после пары бессонных ночей ... и большого количества кофе ... я не могу выяснить причину root моей проблемы.
Читая некоторую документацию по inte rnet, в частности https://www.lambdatest.com/blog/eradicating-memory-leaks-in-javascript, я уже внес некоторые изменения, такие как изменение объявления переменных с «var» на «let».
В Chrome, я запускаю скрипт в течение 2 1/2 минут и профилирую использование памяти (у меня есть файл heaptimeline, если он может помочь, но здесь я не совсем уверен как это проанализировать?):
Кроме того, я запросил у консоли:
производительность. memory.usedJSHeapSize и получил несколько изменяющихся значений: 3430886, 3195206, 4743246, 3402767, et c
performance.memory.jsHeapSizeLimit и получил: 4294705152
Есть ли у кого-нибудь подсказки, с чего начать расследование, зная, что возможности отладки этого планшета не такие продвинутые, как в современном браузере? Моему планшету "уже" 5 лет ... Обновление этого планшета не вариант.
Большое спасибо за то, что вы прочитали меня, и я очень надеюсь, что мой пост понятен, хорошо документирован и в будущем, может помочь другим провести спокойные ночи :)
Код моей html страницы (названной в честь 'screen_saver. html) следующий:
<!DOCTYPE html>
<html>
<head>
<title>Domoos | Screen saver screen</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta http-equiv="pragma" content="no-cache">
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="css/mystyle_saver.css?rnd=999" />
<script type="text/javascript" src="scripts/date_time.js"></script>
<script type="text/javascript" src="scripts/screensaver_run.js"></script>
</head>
<body onload="runScreenSaver(); setup();">
<div style="position:absolute" id="randomPlacement">
<p><img src="assets/pictures/texte_sortie_veille.png" alt ="" style="width:90px;height:90px;" border="0"></p>
</div>
<div id="svg">
<svg height="210" width="1020">
<line x1="11" y1="100" x2="1015" y2="100" style="stroke:rgb(69,69,66);stroke-width:3" />
</svg>
</div>
<div id="date"></div>
<div id="time"></div>
<div id="icon_alarm">
<img id="img_alarm" src="assets/icons/alarme_eteinte.png" alt ="" style="width:27px;height:35px;">
</div>
<div id="tag_temperature">
<p>21°C</p>
</div>
<div id="tag_free_text">
<p>151<sup>ème</sup> jour de l'année 2020.<br>Bonsoir</p>
</div>
<div id="meteo_icon">
<img src="assets/meteo_icons/eclaircies-big.png" alt="" style="width:40px;height:40px;">
</div>
<div id="tag_weather_condition">
<p>Eclaircies</p>
</div>
</body>
</html>
Код моего javasript файл screensaver_run. js:
function runScreenSaver()
{
let xmin = 0;
let xmax = 890;
let ymin = 0;
let ymax = 430;
let sDate;
let sTime;
let bOverlapAuthorised;
let bDisplayPos;
let zRandomImage;
let xCoord;
let yCoord;
let xCoordStr;
let yCoordStr;
bOverlapAuthorised = true;
bDisplayPos = false;
// If overlap is forbidden, the x min and y min parameters will be redefined to be slightly below the line
if (!bOverlapAuthorised)
{
xmin = 15;
ymin = 130;
}
// Computes a random x and y, based on the min and ma
xCoord = Math.floor((Math.random()*xmax)+xmin);
yCoord = Math.floor((Math.random()*ymax)+ymin);
xCoordStr = xCoord.toString() + "px";
yCoordStr = yCoord.toString() + "px";
zRandomImage = document.getElementById("randomPlacement");
zRandomImage.style.left = xCoordStr;
zRandomImage.style.top = yCoordStr;
// Instead of displaying a message in the 'tag_free_text',
// shows the randomly defined coordinates of the 'randomPlacement' object
if (bDisplayPos)
{
document.getElementById("tag_free_text").innerHTML = 'X:' + xCoordStr + '<br>Y:' + yCoordStr;
}
document.getElementById("date").innerhtml=getTimeDate('date');
getAlarmDataFromDatabase();
zRandomImage = null;
xCoord = null;
yCoord = null;
xCoordStr = null;
yCoordStr = null;
setTimeout('runScreenSaver()','3500');
}
function setup()
{
this.addEventListener("mousemove", exitScreenSaver, false);
this.addEventListener("mousedown", exitScreenSaver, false);
this.addEventListener("keypress", exitScreenSaver, false);
this.addEventListener("DOMMouseScroll", exitScreenSaver, false);
this.addEventListener("mousewheel", exitScreenSaver, false);
this.addEventListener("touchstart", exitScreenSaver, false);
this.addEventListener("MSPointerMove", exitScreenSaver, false);
}
function getAlarmDataFromDatabase()
{
let ajax = new XMLHttpRequest();
let id_component;
let technical_name_html;
let comp_value;
let data;
ajax.open("GET", "php/data4screensaver1.php", true);
ajax.send();
ajax.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
data = JSON.parse(this.responseText);
for(var a = 0; a < data.length; a++)
{
id_component = data[a]['id_component'];
technical_name_html = data[a]['technical_name_html'];
comp_value = parseInt(data[a]['value']);
}
data = null;
console.log("ID Component: " + id_component);
//console.log("Valeur de l'alarme : " + comp_value);
switch (comp_value)
{
case 0:
case 50:
case 100:
displayPictureAlarm(comp_value);
break;
default:
displayPictureAlarm(-1);
break;
}
}
};
ajax = null;
id_component = null;
technical_name_html = null;
comp_value = null;
}
function exitScreenSaver(e)
{
goActive(e);
}
function goActive(event)
{
// do something
console.log(".. active ..");
//event.preventDefault();
this.removeEventListener("mousemove", exitScreenSaver);
this.removeEventListener("mousedown", exitScreenSaver);
this.removeEventListener("keypress", exitScreenSaver);
this.removeEventListener("DOMMouseScroll", exitScreenSaver);
this.removeEventListener("mousewheel", exitScreenSaver);
this.removeEventListener("touchstart", exitScreenSaver);
this.removeEventListener("MSPointerMove", exitScreenSaver);
window.open("index.html","_self");
}
function displayPictureAlarm(pValue)
{
let z;
z = document.getElementById("img_alarm");
if (pValue == 0) // désarmée
{
z.src = "assets/icons/alarme_desarmee.png";
}
if (pValue == 50) // partielle
{
z.src = "assets/icons/alarme_partielle.png";
}
if (pValue == 100) // totale
{
z.src = "assets/icons/alarme_totale.png";
}
if (pValue == -1) // éteinte
{
z.src = "assets/icons/alarme_eteinte.png";
}
z = null;
}
Код моего javascript файла datetime. js (как это вызывается в методе runScreenSaver выше):
function getDate(id)
{
date = new Date;
year = date.getFullYear();
month = date.getMonth();
month += 1;
d = date.getDate();
day = date.getDay();
days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
if (d<10)
{
d = "0"+d;
}
if(month<10)
{
month = "0"+month;
}
result = ''+days[day]+' '+d+'.'+month+'.'+year;
result = days[day]+' '+d+'.'+month+'.'+year;
document.getElementById(id).innerHTML = result;
setTimeout('getDate("'+id+'");','1000');
return true;
}
function getTimeDateMainScreen()
{
var za;
var zb;
var zc;
var mydate;
var result1;
var result2;
var result3;
mydate = new Date;
year = mydate.getFullYear();
month = mydate.getMonth();
day = mydate.getDate();
weekday = mydate.getDay();
hrs = mydate.getHours();
mns = mydate.getMinutes();
secs = mydate.getSeconds();
days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
month += 1;
if (day < 10)
{
day = "0" + day;
}
if(month < 10)
{
month = "0" + month;
}
if(hrs < 10)
{
hrs = "0" + hrs;
}
if(mns < 10)
{
mns = "0" + mns;
}
if(secs < 10)
{
secs = "0" + secs;
}
//result = ''+days[weekday]+' '+d+'.'+month+'.'+year;
//result = days[weekday]+' '+d+'.'+month+'.'+year;
result1 = day + "." + month + "." + year;
result2 = days[weekday];
result3 = hrs + ":" + mns + ":" + secs;
za = document.getElementById("curr_date");
zb = document.getElementById("curr_weekday");
zc = document.getElementById("curr_time");
za.innerHTML = result1;
zb.innerHTML = result2;
zc.innerHTML = result3;
za = null;
zb = null;
zc = null;
mydate = null;
result1 = null;
result2 = null;
result3 = null;
setTimeout('getTimeDateMainScreen();','500');
}
function getTime(id)
{
date = new Date;
h = date.getHours();
if(h<10)
{
h = "0"+h;
}
m = date.getMinutes();
if(m<10)
{
m = "0"+m;
}
s = date.getSeconds();
if(s<10)
{
s = "0"+s;
}
result = ''+h+':'+m+':'+s;
document.getElementById(id).innerHTML = result;
setTimeout('getTime("'+id+'");','1000');
return true;
}
function getTime2()
{
date = new Date;
h = date.getHours();
if(h<10)
{
h = "0"+h;
}
m = date.getMinutes();
if(m<10)
{
m = "0"+m;
}
s = date.getSeconds();
if(s<10)
{
s = "0"+s;
}
result = ''+h+':'+m+':'+s;
document.getElementById("time").innerHTML = result;
setTimeout('getTime2();','1000');
}
function getTimeDate(id)
{
let date;
let year;
let month;
let d;
let day;
let days;
let h;
let m;
let s;
let result;
date = new Date;
console.log("J'affiche la date3");
year = date.getFullYear();
month = date.getMonth();
month += 1;
d = date.getDate();
day = date.getDay();
days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
h = date.getHours();
m = date.getMinutes();
s = date.getSeconds();
if (d<10)
{
d = "0"+d;
}
if(month<10)
{
month = "0"+month;
}
if(h<10)
{
h = "0"+h;
}
if(m<10)
{
m = "0"+m;
}
if(s<10)
{
s = "0"+s;
}
result = ''+days[day]+' '+d+'.'+month+'.'+year +' ' + h+':'+m+':'+s;
document.getElementById(id).innerHTML = result;
date = null;
year = null;
month = null;
d = null;
day = null;
days = null;
h = null;
m = null;
s = null;
result = null;
setTimeout('getTimeDate("'+id+'");','1000');
return true;
}
И, наконец, вот мой php (data4screensaver1. php) для извлечения данных из моей mysql базы данных:
<?php
$host = "ip_Address_db";
$db_user_encoded = "user_encoded";
$db_password_encoded = "pw_encoded";
$db_name_encoded = "db_name_encoded";
$conn = mysqli_connect($host, (encrypt_decrypt('decrypt', $db_user_encoded)), (encrypt_decrypt('decrypt', $db_password_encoded)), (encrypt_decrypt('decrypt', $db_name_encoded )));
$result = mysqli_query($conn, "CALL sp_tbl_domotique_components_get_lab61()");
$data = array();
while ($row = mysqli_fetch_object($result))
{
array_push($data, $row);
}
echo json_encode($data);
exit();
function encrypt_decrypt($action, $string)
{
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = '$SecretKey$';
$secret_iv = '$SecretIV$';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if ( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
} else if( $action == 'decrypt' ) {
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
?>