Don't look at all of my code, just the wait() and notify() methods I need to pause the run() method after the loop has finished its work and resume it in the onButtonClick() class, but when I do this I get an exception: current thread is not owner. How do I implement what I wrote in the title of the question
private boolean isFirstPage;
private CommandContext ctx;
private ArrayList<String> linkQuestion;
private Message message;
private int page;
public QuestionListThreads(boolean isFirstPage, CommandContext ctx, ArrayList<String> linkQuestion, Message message) {
this.isFirstPage = isFirstPage;
this.ctx = ctx;
this.linkQuestion = linkQuestion;
this.message = message;
}
#Override
public void run() {
synchronized (this) {
EmbedBuilder eb = new EmbedBuilder();
if (isFirstPage) {
for (; page < 3; page++) {
eb.addField("page " + page, "[link]" + linkQuestion.get(page), false);
}
ctx.getChannel().sendMessage(eb.build()).setActionRow(Button.secondary("next", "next")).queue();
} else {
page = 3;
for (int i = 0; i < 3; i++, page++) {
eb.addField("page " + page, "[link]" + linkQuestion.get(page), false);
if (i == 2) {
message.editMessage(eb.build()).setActionRow(Button.secondary("next", "next")).queue();
try {
this.wait();
i = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public void onButtonClick(ButtonClickEvent event) {
if (event.getComponentId().equals("next")) {
new QuestionListThreads(false, null, QuestionListCommand2.getLinkQuestion(),
event.getMessage()).notify();
}
Related
So I developed an Android application which acts as a server for my Android game(two separated apps), both applications were written in Java.
Previously I got messages on the Log like: "Skipped 2000 frames. The main thread could be overworking".
This is the code of my app, it's made of only the MainActivity:
I tried to introduce concurrent Threads in order to make the main thread lighter. Now the skipped n frames message isn't showed anymore but messages such like the followings are shown anyways.
"Alloc concurrent copying GC freed", "Starting a blocking GC alloc", "Waiting for a blocking GC alloc", "WaitForGcToComplete blocked alloc on HeapTrim" and all of this ends with
Throwing OutOfMemoryError "Failed to allocate a 32 byte allocation with 15604408 free bytes and 14MB until OOM, target footprint 268435456, growth limit 268435456; failed due to fragmentation (largest possible contiguous allocation 0 bytes)" (VmSize 5539048 kB).
I tried to deallocate some objects (lines of code which contains "x = null") but it didn't solve. Furthermore I checked with a log if there is some sort of endless loop but it doesn't seem to be the case.
public class MainActivity extends AppCompatActivity {
private static ActivityMainBinding binding;
private WSocServer server;
private int port = 8080;
private boolean isOnline = false;
private static ArrayList<String> logs = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
binding.openConnection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!isOnline) {
isOnline = true;
server = new WSocServer(port);
server.start();
Toast toast = Toast.makeText(view.getContext(),"Server is on", Toast.LENGTH_LONG);
toast.show();
Log.i("WebSocket Server", "Started on port " + server.getPort());
}
else{
Snackbar snack = Snackbar.make(view ,"We are already online!", Snackbar.LENGTH_INDEFINITE);
snack.setAction("Got it", new View.OnClickListener() {
#Override
public void onClick(View view) {
snack.dismiss();
}
});
snack.show();
}
}
});
binding.closeConnection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(isOnline) {
isOnline = false;
logs.clear();
Toast toast = Toast.makeText(view.getContext(),"Server is off", Toast.LENGTH_LONG);
toast.show();
try {
server.stop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
Snackbar snack = Snackbar.make(view ,"We are already offline!", Snackbar.LENGTH_INDEFINITE);
snack.setAction("Got it", new View.OnClickListener() {
#Override
public void onClick(View view) {
snack.dismiss();
}
});
snack.show();
}
}
});
}
private static void addOnView(){
ConstraintLayout cl = binding.logsView;
Handler h = new Handler(Looper.getMainLooper());
for(int i = 0; i < logs.size(); i++){
TextView tv = new TextView(binding.getRoot().getContext());
tv.setTextSize(16);
tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
tv.setPadding(40,180*(i+1),40,0);
tv.setText(logs.get(i));
Runnable r = new Runnable() {
#Override
public void run() {
cl.addView(tv);
}
};
h.post(r);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
server.stop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class WSocServer extends WebSocketServer {
private List<String> matchUsers;
private Integer timerSeconds;
private UUID matchId;
//a key represents a match to which an array of extracted numbers is associated
private Hashtable<String,Integer[]> matchExtractedNumbers = new Hashtable<>();
private Hashtable<String, Collection<WebSocket>> matchClients = new Hashtable<>();
private Hashtable<String,Hashtable<String,ArrayList<String>>> users_scorePerMatch = new Hashtable<>();
private Hashtable<String,WebSocket> clientConnection = new Hashtable<>();
private void initTimer(){
timerSeconds = 60;
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
if(timerSeconds > 0) timerSeconds--;
else {
timerSeconds = 60; timer.cancel(); timer.purge();
}
}
};
timer.schedule(task,0L,1000L);
}
private String UsersListToString(List list){
return list.toString().replace("[","").replace("]","");
}
private Integer[] generateExtractedNumbers(){
Integer[] callerBoard = new Integer[90];
List<Integer> boardPool = new ArrayList<>();
boardPool.addAll(Arrays.asList(IntStream.rangeClosed(1,90).boxed().toArray(Integer[]::new)));
for(int i = 0; i < 90; i++){
int rng = ThreadLocalRandom.current().nextInt(0,90-i);
callerBoard[i] = boardPool.remove(rng);
}
return callerBoard;
}
private void initMatch(){
matchId = UUID.randomUUID();
Integer[] matchBoard = generateExtractedNumbers();
matchExtractedNumbers.put(matchId.toString(),matchBoard);
matchClients.put(matchId.toString(),clientConnection.values());
Hashtable<String,ArrayList<String>> matchData = new Hashtable<>();
for(String user: matchUsers) matchData.put(user,new ArrayList<>());
users_scorePerMatch.put(matchId.toString(), matchData);
}
private Integer getExtractedNumber(String match, Integer turn){
if(turn >= 90) return -1;
Integer[] thisMatchExtractedNumbers = matchExtractedNumbers.get(match);
Integer returning = thisMatchExtractedNumbers[turn];
thisMatchExtractedNumbers = null;
return returning;
}
public WSocServer(int port){
super(new InetSocketAddress(port));
}
public WSocServer(InetSocketAddress address) {
super(address);
}
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Log.i("WebSocket(open)", conn.getRemoteSocketAddress().getAddress().getHostAddress() + " entered the room!");
logs.add(conn.getRemoteSocketAddress().getAddress().getHostAddress() + " entered the room!");
matchUsers = new ArrayList<>();
matchUsers.addAll(Arrays.asList("user1","user2","user3","user4","user5"));
}
});
thread.start();
}
#Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Log.i("WebSocket(close)", conn + " has left the room! Reason: " + reason);
logs.add(conn + " has left the room!");
}
});
thread.start();
}
#Override
public void onMessage(WebSocket conn, String message) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
logs.add(message + " from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
Log.i("WebSocket(message)", conn + ": " + message);
MainActivity.addOnView();
if(message.startsWith("username")){
if(matchUsers.size() < 6){
String user = message.replace("username;","");
if(!matchUsers.contains(user)) {
matchUsers.add(user);
clientConnection.put(user,conn);
}
String sending = "matchUsers;" + UsersListToString(matchUsers);
conn.send(sending);
}
else conn.send("errorUsername");
}
else if(message.equals("timerStart")){
initTimer();
if(matchUsers.size() < 6){
String sending = "timeStarter;" + timerSeconds.toString();
conn.send(sending);
}
else conn.send("errorTimer");
}
else if(message.equals("getMatchId")){
if(!matchUsers.isEmpty()){
initMatch();
matchUsers.clear();
}
String sending = "matchId;" + matchId.toString();
conn.send(sending);
}
else if(message.startsWith("inGame")){
String[] fields = message.split(";");
String matchId = fields[1].split("=")[1];
int turn = Integer.parseInt(fields[2].split("=")[1]);
Integer extraction = getExtractedNumber(matchId,turn);
fields = null;
conn.send("extracted=" + extraction.toString());
}
else if(message.startsWith("score")){
String matchId = message.split(";")[1].split("=")[1];
String score = message.split(";")[0].split("=")[1];
WebSocket[] clients = matchClients.get(matchId).toArray(new WebSocket[0]);
String user = "";
Enumeration<String> keys = clientConnection.keys();
String key = keys.nextElement();
while(!key.isEmpty()){
if(clientConnection.get(key) == conn) {
user = key;
break;
}
key = keys.nextElement();
}
keys = null;
Hashtable<String,ArrayList<String>> tmp = users_scorePerMatch.get(matchId);
ArrayList<String> tmp_list = tmp.get(user);
tmp_list.add(score);
tmp.replace(user,tmp_list);
users_scorePerMatch.replace(matchId,tmp);
for(int i = 0; i < clients.length; i++){
clients[i].send("statement;" + user + " got " + score + " with");
}
clients = null;
}
else if(message.startsWith("endMatchData")){
String matchId = message.split(";")[1].split("=")[1];
Hashtable<String,ArrayList<String>> users_ofMatch = users_scorePerMatch.get(matchId);
ArrayList<String> users = new ArrayList<>();
Enumeration<String> e = users_ofMatch.keys();
while(e.hasMoreElements()){
Log.e("endmatchdata","a");
users.add(e.nextElement());
}
e = null;
String sending = "matchEndData;";
for(String user: users) sending += user + "=" + UsersListToString(users_ofMatch.get(user)) + ":";
users_ofMatch = null;
conn.send(sending);
}
else if(message.startsWith("totalEnd")){
String matchId = message.split(";")[1].split("=")[1];
if(matchClients.get(matchId)!=null) {
WebSocket[] clients = matchClients.get(matchId).toArray(new WebSocket[0]);
for (WebSocket client : clients) client.close();
Enumeration<String> e = clientConnection.keys();
boolean exit = false;
while (e.hasMoreElements() && !exit) {
Log.e("totalend", "while");
for (WebSocket client : clients) {
Log.e("totalend", "for");
String tmp = e.nextElement();
if (clientConnection.get(tmp) == client) {
clientConnection.remove(tmp);
exit = true;
break;
}
}
}
e = null; clients = null;
matchClients.remove(matchId);
users_scorePerMatch.remove(matchId);
matchExtractedNumbers.remove(matchId);
}
}
}
});
thread.start();
}
#Override
public void onMessage(WebSocket conn, ByteBuffer message) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Log.i("WebSocket(message)", conn + ": " + message );
}
});
thread.start();
}
public static void main(String[] args){
}
#Override
public void onError(WebSocket conn, Exception ex) {
ex.printStackTrace();
}
#Override
public void onStart() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Log.i("WebSocket", "Server started!");
}
});
thread.start();
}
}
}
EDIT: The thing seems to be happening at the end of the match(i.e in the message.startsWith("totalEnd") or message.startsWith("endmatchdata") if cases in the onMessage method
EDIT 2: I found out that the addOnView function was badly written.
I changed it into
private static void addOnView(){
ConstraintLayout cl = binding.logsView;
Handler h = new Handler(Looper.getMainLooper());
final TextView tv = new TextView(binding.getRoot().getContext());
tv.setTextSize(16);
tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
tv.setPadding(40,180*(logs.size()+1),40,0);
tv.setText(logs.get(logs.size()-1));
Runnable r = new Runnable() {
#Override
public void run() {
cl.addView(tv);
}
};
h.post(r);
h = null;
r = null;
}
And it solved.
I get out of memory error if the function doesWifiExist is false if it is true every thing works normally.Can someone tell me what m i doing wrong
The idea is to get a list of wifi networks nearby and check if the inserted network exists in the list.
Here is the wifi network scanning code and the the function that checks if the wifi network exists.
MainActivity:
private WiFiConnection _wifiConnection = null;
static final int MY_PERMISSIONS_REQUEST = 1042;
private static final String PERMISSIONS_TAG = "PERMISSION";
...
#Override
protected void onStart() {
super.onStart();
_wifiConnection = new WiFiConnection(this);
startScan();
}
#Override
protected void onStop() {
super.onStop();
_wifiConnection.stopScan();
unregisterReceiver(_wifiScanReceiver);
}
void startScan() {
checkPermission(this);
registerReceiver(_wifiScanReceiver,
new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Thread t = new Thread(_wifiConnection.getWifiScanner());
t.start();
}
private final BroadcastReceiver _wifiScanReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
if (_wifiConnection != null && _wifiConnection.isWifiEnabled()) {
_wifiConnection.updateScanData();
}
}
}
};
public static boolean checkPermission(Activity activity) {
boolean permission = true;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<String> requiringList = new ArrayList<>();
permission = activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
Log.d(PERMISSIONS_TAG, "ACCESS_COARSE_LOCATION: " + permission);
if (!permission) {
requiringList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (requiringList.size() > 0) {
String[] stringArray = requiringList.toArray(new String[0]);
activity.requestPermissions(stringArray, MY_PERMISSIONS_REQUEST);
}
}
return permission;
}
private boolean doesWifiExist(String s){
String[] array = s.split(" ");
String ssid = array[0];
boolean flag = false;
//Check if wifi exists in the area
for(int i = 0 ; i < _wifiConnection.getListSSIDs().size(); i++){
if(_wifiConnection.getListSSIDs().get(i).equals(ssid)){
flag = true;
break;
}
}
return flag;
}
WiFiConnection class:
public class WiFiConnection
{
private static final int SCAN_INTERVAL = 5000;
final private List<String> _listSSIDs = new ArrayList<>();
private WifiManager _wifiManager;
private final WiFiScanner _startScan = new WiFiScanner();
private List<ScanResult> scanResults;
WiFiConnection(Activity activity) {
_wifiManager = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
}
//Puts wifi networks in a list
public List<String> getListSSIDs() {
for(int i = 0; i < scanResults.size(); i++)
{
_listSSIDs.add(scanResults.get(i).SSID);
}
return _listSSIDs;
}
WiFiScanner getWifiScanner() { return _startScan; }
void stopScan() { _startScan.stop(); }
boolean isWifiEnabled() { return _wifiManager.isWifiEnabled(); }
//Gets the wifi networks
void updateScanData() {
if ((_wifiManager != null && _wifiManager.isWifiEnabled())) {
scanResults = _wifiManager.getScanResults();
}
}
//Scans at an interval
private class WiFiScanner implements Runnable
{
private boolean _stop = false;
public void stop() {_stop = true;}
#Override
public void run() {
while (!_stop) {
_listSSIDs.clear();
_wifiManager.startScan();
try {
Thread.sleep(SCAN_INTERVAL);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
The code where doesWifiExist is used.
//Check if wifi exists in the area
if(doesWifiExist(barcode.displayValue)){
//Connects to wifi
WifiConnect(barcode.displayValue);
//Saves item in db
insertItem();
if(networkSecurity.equals("None")){
networkPass = empty;
}
//Adds item to recyclerview
historyItems.add(0, new HistoryItem(wifiName + " " + networkSSID, wifiPass + " " + networkPass));
adapter.notifyItemInserted(0);
} else
Snackbar.make(findViewById(R.id.main_activity), R.string.snackInvalidQrCode, Snackbar.LENGTH_SHORT).show();
This method is called many times, and it everytime adds all scanResults at the end of field _listSSIDS.
public List<String> getListSSIDs() {
for(int i = 0; i < scanResults.size(); i++)
{
_listSSIDs.add(scanResults.get(i).SSID);
}
return _listSSIDs;
}
Use a local variable with a new List or better Set there.
Instead replace
for(int i = 0 ; i < _wifiConnection.getListSSIDs().size(); i++){
if(_wifiConnection.getListSSIDs().get(i).equals(ssid)){
flag = true;
break;
}
}
with
flag = _wifiConnection.hasSSID(String ssid);
public boolean hasSSID(String ssid) {
for (int i = 0; i < scanResults.size(); i++) {
if (ssid.equals(scanResults.get(i).SSID)) {
return true;
}
}
return false;
}
I got a few markers and update a position of this markers (I send request for server). But when I put new markers I did this:
public void putMarkers() {
Singleton si = Singleton.getInstance();
Drawable newMarker = getApplication().getResources().getDrawable(R.drawable.znacznik_new);
Drawable newMarkerAktywny = getApplication().getResources().getDrawable(R.drawable.ikona_znacznik_pojazd_aktywna);
mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext());
activeOverlayItemArray.clear();
anotherOverlayItemArray.clear();
for(ObjectDefExtends object : si.getListaVisible()){
if (object.lon == null) object.lon = 0.0;
if (object.lat == null) object.lat = 0.0;
/*if (si.getListaVisible().get(a).lon!=null&&si.getListaVisible().get(a).lon!=0)*/
if (object == Singleton.getInstance().currentObject) {
activeOverlayItemArray.add(new OverlayItem(object.name,
object.name, new GeoPoint(object.lat, object.lon)));
} {
anotherOverlayItemArray.add(new OverlayItem(object.name,
object.name, new GeoPoint(object.lat, object.lon)));
}
}
anotherItemizedIconOverlay = new ItemizedIconOverlay<>(anotherOverlayItemArray, newMarker, new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
indexs = index + 1;
mPin.hideInfoWindow();
mapView.getOverlays().remove(mPin);
mPin.setPosition(anotherItemizedIconOverlay.getItem(index).getPoint());
mPin.setTitle(anotherItemizedIconOverlay.getItem(index).getTitle());
try {
tvStreetName.setText(getCityAndStreet(anotherItemizedIconOverlay.getItem(index).getPoint().getLatitude(), anotherItemizedIconOverlay.getItem(index).getPoint().getLongitude(), getBaseContext()));
} catch (IOException e) {
e.printStackTrace();
}
currentNumber = index;
Singleton.getInstance().setCurrentObjectIndex(currentNumber);
Log.e("azymut ", Singleton.getInstance().getListaODE().get(currentNumber).azimuth + "");
updateEverything();
mPin.showInfoWindow();
mapView.getOverlays().add(mPin);
return true;
}
#Override
public boolean onItemLongPress(final int index, final OverlayItem item) {
return false;
}
}, mResourceProxy);
activeItemizedIconOverlay = new ItemizedIconOverlay<>(activeOverlayItemArray, newMarkerAktywny, new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
mPin.hideInfoWindow();
mapView.getOverlays().remove(mPin);
mPin.setPosition(activeItemizedIconOverlay.getItem(index).getPoint());
mPin.setTitle(anotherItemizedIconOverlay.getItem(index).getTitle());
currentNumber = index;
Singleton.getInstance().setCurrentObjectIndex(currentNumber);
updateEverything();
mPin.showInfoWindow();
mapView.getOverlays().add(mPin);
return true;
}
#Override
public boolean onItemLongPress(final int index, final OverlayItem item) {
return false;
}
}, mResourceProxy);
for (int a = 0; a < anotherItemizedIconOverlay.size(); a++) {
if (si.listaVisible.indexOf(Singleton.getInstance().currentObject) == a) {
activeItemizedIconOverlay.removeAllItems();
activeItemizedIconOverlay.addItem(new OverlayItem(
si.getListaVisible().get(a).name,
si.getListaVisible().get(a).name,
new GeoPoint(si.getListaVisible().get(a).lat,
Singleton.getInstance().getListaVisible().get(a).lon)));
mPin.setPosition(anotherItemizedIconOverlay.getItem(a).getPoint());
mPin.setAnchor(0.5f, 0.5f);
mPin.setIcon(getResources().getDrawable(R.drawable.pusty));
mPin.setTitle(anotherItemizedIconOverlay.getItem(a).getTitle());
break;
}
}
runOnUiThread(new Runnable() {
#Override
public void run() {
mapView.getOverlays().add(mPin);
mapView.getOverlays().add(anotherItemizedIconOverlay);
mapView.getOverlays().add(activeItemizedIconOverlay);
mapView.invalidate();
}
});
}
And this is how I update a position:
public void aktualizujCoInterwal(int interwal) {
aktualizacja = true;
executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new Runnable() {
public void run() {
Log.e("aktualizacja", "akt");
if (timeout) {
executor.shutdown();
timedOut();
} else {
aktualizacjaDanych();
}
}
}, 0, interwalAktualizacji, TimeUnit.SECONDS);
}
public void aktualizacjaDanych() {
SmokConnectorImplPortBinding srv1 = new SmokConnectorImplPortBinding(null, URL);
try {
Singleton si = Singleton.getInstance();
ObjectLastStateResult lastState2;
lastState2 = srv1.GetObjectLastState(uid, now);
int rozmiarNowych = lastState2.objectState.size();
int value = (Integer) lastState2.getProperty(0);
if (value != 1) {
timeout = true;
executor.shutdownNow();
timedOut();
} else {
int rozmiarObecnych = si.getListaODE().size();
runOnUiThread(new Runnable() {
#Override
public void run() {
//czyszczenie poprzednio dodanych na mape obiektow
anotherOverlayItemArray.clear();
activeOverlayItemArray.clear();
mapView.getOverlays().clear();
}
});
for (int i = 0; i < rozmiarNowych; i++) {
for (int b = 0; b < rozmiarObecnych; b++) {
if (si.getListaODE().get(b).id.equals(lastState2.objectState.get(i).id)) {
if (lastState2.objectState.get(i).lon != null && lastState2.objectState.get(i).lon.doubleValue() != 0) {
if (lastState2.objectState.get(i).lat != null && lastState2.objectState.get(i).lat.doubleValue() != 0) {
si.getListaODE().get(b).lat = lastState2.objectState.get(i).lat.doubleValue();
si.getListaODE().get(b).lon = lastState2.objectState.get(i).lon.doubleValue();
}
si.getListaODE().get(b).azimuth = lastState2.objectState.get(i).azimuth.intValue();
si.getListaODE().get(b).lastDataTime = lastState2.objectState.get(i).dateTime;
si.getListaODE().get(b).statusGPS = lastState2.objectState.get(i).statusGPS;
try {
si.getListaODE().get(b).mySensors = lastState2.objectState.get(i).sensors.sensor;
} catch (NullPointerException e) {
Log.e("Null", "sensory są puste");
}
si.getListaODE().get(b).description1 = lastState2.objectState.get(i).description1;
si.getListaODE().get(b).description2 = lastState2.objectState.get(i).description2;
si.getListaODE().get(b).velocity = lastState2.objectState.get(i).velocity.intValue();
try {
si.getListaODE().get(b).icons = lastState2.objectState.get(i).sensors.icon;
} catch (NullPointerException e) {
Log.e("Null", "sensory są puste");
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
now = DateTime.now();
Singleton si = Singleton.getInstance();
if (si.getListaVisible().size() > 0) {
obiektyNaMape();
updateEverything();
}
showCurrentMarker();
}
All my objects from servers have a azimuth and I rotate a markers icon from all markers, and when a update is done first of all I see a default markers and later I see a rotate markers.
I found out that when i pressed a button to run a while loop, the android app will freeze although the program can run. It seem that i stuck in a loop and i want to make a thread to show the GUI and the other for the main code . I'm new in java and i'm self-learned so i would appreciated if anyone could give me an example how to prevent the app from freezing.
I'm sorry if i didn't explain my problem well.
Thank you
Here is my code
public class TachoCount extends Thread {
public boolean isConnected;
protected static final String TAG = "TachoCount";
NXTConnector conn;
//_message = (TextView) findViewById(R.id.messageText);
//final TextView textView = (TextView) findViewById(R.id.textView1);
public static NXTConnector connect(final CONN_TYPE connection_type) {
Log.d(TAG, " about to add LEJOS listener ");
NXTConnector conn = new NXTConnector();
conn.setDebug(true);
conn.addLogListener(new NXTCommLogListener() {
public void logEvent(String arg0) {
Log.e(TAG + " NXJ log:", arg0);
}
public void logEvent(Throwable arg0) {
Log.e(TAG + " NXJ log:", arg0.getMessage(), arg0);
}
});
switch (connection_type) {
case LEGO_LCP:
conn.connectTo("btspp://NXT", NXTComm.LCP);
break;
case LEJOS_PACKET:
conn.connectTo("btspp://");
break;
}
return conn;
}
public TachoCount() {
}
public void closeConnection() {
try {
Log.d(TAG, "TachoCount run loop finished and closing");
conn.getNXTComm().close();
} catch (Exception e) {
} finally {
conn = null;
}
}
public void establishConnection(){
conn = TachoCount.connect(CONN_TYPE.LEGO_LCP);
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
NXTInfo info = conn.getNXTInfo();
if (info.connectionState== NXTConnectionState.LCP_CONNECTED)
{
isConnected = true;
// set
//textView.setText("NXT is here");
}
}
public void forward(){
Motor.A.setSpeed(300);
Motor.C.setSpeed(300);
Motor.A.forward();
Motor.C.forward();
}
public void backward(){
Motor.A.setSpeed(300);
Motor.C.setSpeed(300);
Motor.A.backward();
Motor.C.backward();
}
public void byebye(){
Motor.A.stop();
Motor.C.stop();
}
public int getSensorValue()
{
int val = 0;
LightSensor ls = new LightSensor(SensorPort.S3);
val = ls.readValue();
return val;
}
public void linefollower()
{
run();
}
public void run()
{
int min = 30, max = 37, readLight = 0, Mspeed = 90, Mspeed2 = 20;
LightSensor ls = new LightSensor(SensorPort.S3);
while(true){
Motor.A.forward();
Motor.C.forward();
readLight = ls.readValue();
LeJOSDroid.sendMessageToUIThread("Sensor: "+ls.readValue());
if (readLight < min){
readLight = min+1;
}
if (max < readLight){
readLight = max-1;
}
Motor.C.setSpeed(Mspeed + (Mspeed2 * (readLight - min)));
Motor.A.setSpeed(Mspeed + (Mspeed2 * (max - readLight)));
}
}
i tried to change the code. It runs well (although the reading of the
sensor doesn't seem accurate), but then when i push another button,
nothing happens
public void linefollower()
{
Thread thread = new Thread(runnable);
thread.start();
}
Runnable runnable = new Runnable ()
{
public void run(){
int min = 30, max = 37, readLight = 0, Mspeed = 90, Mspeed2 = 20;
LightSensor ls = new LightSensor(SensorPort.S3);
while(true){
Motor.A.forward();
Motor.C.forward();
readLight = ls.readValue();
LeJOSDroid.sendMessageToUIThread("Sensor: "+ls.readValue());
if (readLight < min){
readLight = min+1;
}
if (max < readLight){
readLight = max-1;
}
Motor.C.setSpeed(Mspeed + (Mspeed2 * (readLight - min)));
Motor.A.setSpeed(Mspeed + (Mspeed2 * (max - readLight)));
}
}
};
Try using Runnable or background worker
Your loop looks infinite, it's always true. Also, it's probably better to do heavy tasks in an asynctask activity.
Check the official info: http://developer.android.com/reference/android/os/AsyncTask.html
I have a small, but very strange problem...
I need to read fragments from file and place them into array, which is out of reading thread, but when i wants to get them from current thread, i'm getting empty arrray.
My brain crashed at this stuff:
private int fragmentSize = 262144, fragmentCacheElements = 32, fragmentCacheUpdates = 0;
// Cache 8Mb (265Kb*32)(262144*32)
private String[] fragmentCache;
private boolean needCacheUpdate, end;
private Thread cacheThread = new Thread(new Runnable()
{
String[] fCache = new String[fragmentCacheElements];
#Override
public void run()
{
while (!end) {
for (int i = 0; i < fragmentCacheElements; ++i) {
fCache[i] = new String(loadFragment(i + fragmentCacheUpdates * fragmentCacheElements));
}
while (true) {
if (needCacheUpdate) {
++fragmentCacheUpdates;
fragmentCache = fCache;
// fragment[0] != null
needCacheUpdate = false;
break;
}
}
}
}
});
public static void main(String[] args)
{
fragmentCache = new String[fragmentCacheElements];
cacheThread.start();
updateCache();
// Notifying client
}
// Getting fragment from cache to send it to client
// AND WHY fragment[0] == null ???
private String getCache(int id)
{
if (id >= fragmentCacheUpdates * fragmentCacheElements) {
updateCache();
}
return fragmentCache[id - (fragmentCacheUpdates - 1) * fragmentCacheElements];
}
private void updateCache()
{
needCacheUpdate = true;
while (true) {
if (!needCacheUpdate) {
break;
}
}
}
Any suggestions?
Try
fragmentCache = Arrays.copyOf(fCache, fCache.length);