Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Regular Contributor
pablo_ivan57
Posts: 60
Registered: ‎02-24-2011
My Device: Not Specified

Serious networking problems on app

[ Edited ]

Hello I have been fighting with slow networking performance on the Blackberry for more than a week now. What I'm doing is retrieving a 20k file with the device, parsing it and showing the results on the screen. Sometimes it just takes 5 seconds to complete everything, other times it takes 60 seconds to 1 and a half minute? I really have no idea what could be wrong. Garbage collection?... On other posts other users told me that If I don't see a waiting clock on the screen, memory storage shouldn't be an issue, and I haven't seen it yet. We need to resolve this issue right now because are over the deadlines. Please I really really need some help. I'll post all the code and the key classes to see if you can spot any kind of problem that could be the reason of the lag.

 

Also if you have any suggestions about the code on any topic, it would be great to hear them. I really have been searching for answers these week.

I even tested with the same simulator as the device. (Blackberry Curve 9300)... in the simulator the application is perfect,  low times, it's responsive... and it's connected to the same test server. However in the device the history is different. 13 seconds average time to retrieve a 20k file...

The processing is not an issue, it's always the same even on the device, it takes always approximately 3 seconds to parse the whole file, and 1 sec more or less to draw the result screen. So I don't think it's a processing problem. However it's not a network issue either, We have tested the network and the same RestService with an iPhone and no problems so far, less than 1 second donwloading all the data...

 

One thing to note is that we're using a corporate wifi network wich has an Http proxy, however I haven't found yet a way to manually specify the proxy host and port, neither the username and password, it does it automatically...?? That could be the root of the problem.

 

Thank you so much!!, and please if you want me to explain better the issue, the code or if you need me to upload more classes I'll do it inmediately.

 

 

package ec.com.smx.workflow.movil;

import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;

import javax.microedition.io.HttpConnection;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.progressindicator.ActivityImageField;
import net.rim.device.api.ui.component.progressindicator.ActivityIndicatorView;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.decor.BackgroundFactory;
import net.rim.device.api.util.SimpleSortingVector;
import net.rim.device.api.util.StringProvider;

import com.kruger.exceptions.ParserException;
import com.kruger.networking.HttpError;
import com.kruger.networking.HttpHelper;
import com.kruger.networking.interfaces.HttpDelegate;
import com.kruger.parsing.AbstractParser;

import ec.com.smx.workflow.movil.gui.TableListField;
import ec.com.smx.workflow.movil.manager.TableLayoutManager;
import ec.com.smx.workflow.movil.model.WorkItem;
import ec.com.smx.workflow.movil.model.WorkItemComparator;
import ec.com.smx.workflow.movil.parsing.TareaParser;
import ec.com.smx.workflow.movil.parsing.WorkItemParser;
import ec.com.smx.workflow.movil.properties.BpmServiceResources;
import ec.com.smx.workflow.movil.properties.WorklistMessages;

public class WorkItemListScreen extends StackScreen implements HttpDelegate {

	ActivityIndicatorView activityView;
	SimpleSortingVector tareas;

	VerticalFieldManager manager;
	VerticalFieldManager tableManager;
	TableListField tableListField;
	Font listFont;
	PollTareasThread pollThread;

	int[] columnWidths;
	int[] columnStyles;

	public WorkItemListScreen() {
		super(NO_VERTICAL_SCROLL);
		setTitle(new LabelField("Worklist", Field.FIELD_HCENTER
				| Field.NON_FOCUSABLE));
		manager = new VerticalFieldManager(VERTICAL_SCROLLBAR | VERTICAL_SCROLL
				| FOCUSABLE);

		activityView = new ActivityIndicatorView(FIELD_HCENTER,
				new HorizontalFieldManager());
		Bitmap bitmap = Bitmap.getBitmapResource("waiting.png");
		activityView.createActivityImageField(bitmap, 12, 0);
		ActivityImageField animation = activityView.getAnimation();
		animation.setPadding(0, 5, 0, 0);
		activityView.setLabel("Por favor espere...");
		manager.add(activityView);
		add(manager);

		int unit = Display.getWidth() / 10;
		columnWidths = new int[] { unit, unit * 2, unit * 3, unit * 4 };
		columnStyles = new int[] { TableLayoutManager.USE_PREFERRED_SIZE,
				TableLayoutManager.USE_PREFERRED_SIZE,
				TableLayoutManager.USE_PREFERRED_SIZE,
				TableLayoutManager.USE_PREFERRED_SIZE };
		pollThread = new PollTareasThread(ApplicationPreferences.getInstance()
				.getReloadTime());
		pollThread.start();

	}

	public void reloadData() {

		String url = null;
		if (BpmServiceResources.getInstance().isCurrentEngineWorkflow()) {
			String[] urlParameters = { BpmServiceResources.getInstance().WORKFLOW_FLOW_ID };
			url = BpmServiceResources
					.getInstance()
					.replacePlaceHolderForResource(
							BpmServiceResources.getInstance().WORKFLOW_LISTA_CASOS,
							urlParameters);
		} else {
			url = BpmServiceResources.getInstance()
					.replacePlaceHolderForResource(
							BpmServiceResources.getInstance().IBM_LISTA_CASOS,
							null);

		}

		UiApplication.getUiApplication().invokeLater(new Runnable() {
			public void run() {
				if (!(manager.getField(0) instanceof ActivityIndicatorView)) {
					manager.insert(activityView, 0);
				}
			}
		});
		HttpHelper workListHelper = new HttpHelper(url, null, this,
				HttpConnection.GET, this, false);
		workListHelper.start();

	}

	private class PollTareasThread extends Thread {

		private long pollTime;
		private boolean _stop = false;
		private boolean _suspended = false;

		public PollTareasThread(long sleepTime) {
			pollTime = sleepTime;
		}

		public void run() {
			while (!_stop) {
				try {
					if (!_suspended) {
						reloadData();
					}
					Thread.sleep(pollTime);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

		}

		public void suspend() {
			_suspended = true;
		}

		public void resume() {
			_suspended = false;
		}

		public void stop() {
			_stop = true;
		}
	}

	private VerticalFieldManager createTableLayout() {
		VerticalFieldManager vfm = new VerticalFieldManager();
		if (tareas == null || tareas.isEmpty()) {
			vfm.add(new LabelField(
					WorklistMessages
							.getInstance()
							.getProperties()
							.get("ec.com.smx.workflow.mensajes.autorizaciones.tareas.vacio")));
			return vfm;
		}

		int unit = Display.getWidth() / 10;
		Calendar dateCalendar = Calendar.getInstance();
		String lastDay = "";
		Font workflowFont = Font.getDefault().derive(
				Font.getDefault().getStyle(), 12);

		for (int i = 0; i < tareas.size(); i++) {
			WorkItem item = (WorkItem) tareas.elementAt(i);
			if (BpmServiceResources.getInstance().isCurrentEngineWorkflow()) {
				dateCalendar.setTime(item.getActivityStartDate());
			} else {
				dateCalendar.setTime(item.getTaskDueDate());
			}
			String dayOfMonth = String.valueOf(dateCalendar
					.get(Calendar.DAY_OF_MONTH));
			if (dayOfMonth.length() == 1)
				dayOfMonth = "0" + dayOfMonth;
			String month = String.valueOf(dateCalendar.get(Calendar.MONTH) + 1);
			if (month.length() == 1)
				month = "0" + month;
			String day = dayOfMonth + "/" + month + "/"
					+ String.valueOf(dateCalendar.get(Calendar.YEAR));
			if (!lastDay.equals(day)) {
				lastDay = day;
				Field[][] fields = new Field[1][1];
				VerticalFieldManager separatorManager = new VerticalFieldManager();
				LabelField separatorLabelField = new LabelField(day,
						FIELD_HCENTER);
				int labelWidth = Font.getDefault().getAdvance(day);
				separatorLabelField.setMargin(0, 0, 0,
						((Display.getWidth() - labelWidth) / 2));
				separatorManager.add(separatorLabelField);
				fields[0][0] = separatorManager;
				int[] columnWidths = new int[] { Display.getWidth() };
				int[] paddings = new int[] { 0 };
				TableListField tableField = new TableListField(null, fields,
						columnWidths, paddings);
				// RED COLOR
				// tableField.setBackground(BackgroundFactory
				// .createLinearGradientBackground(0xFF4D4D , 0xFF4D4D, 0xFF8080
				// , 0xFF8080 ));
				// GREY COLOR
				tableField.setBackground(BackgroundFactory
						.createLinearGradientBackground(0xDBDBDB, 0xDBDBDB,
								0xF0F0F0, 0xF0F0F0));
				vfm.add(tableField);
			}

			Field[][] fields = new Field[1][4];
			Object[] userData = { item };
			int[] columnWidths = null;
			int[] paddings = null;
			if (BpmServiceResources.getInstance().isCurrentEngineWorkflow()) {
				Field field = new LabelField(String.valueOf(item
						.getProcessCode()), DrawStyle.ELLIPSIS);
				field.setFont(workflowFont);
				fields[0][0] = field;
				String hour = "";
				if (dateCalendar.get(Calendar.HOUR) == 0
						&& dateCalendar.get(Calendar.AM_PM) == Calendar.PM) {
					hour += "12";
				} else if (String.valueOf(dateCalendar.get(Calendar.HOUR))
						.length() == 2)
					hour += String.valueOf(dateCalendar.get(Calendar.HOUR));
				else
					hour += "0"
							+ String.valueOf(dateCalendar.get(Calendar.HOUR));

				if (String.valueOf(dateCalendar.get(Calendar.MINUTE)).length() == 2)
					hour += ":"
							+ String.valueOf(dateCalendar.get(Calendar.MINUTE));
				else
					hour += ":0"
							+ String.valueOf(dateCalendar.get(Calendar.MINUTE));
				if (dateCalendar.get(Calendar.AM_PM) == Calendar.AM)
					hour += " AM";
				else
					hour += " PM";
				field = new LabelField(hour);
				field.setFont(workflowFont);
				fields[0][1] = field;
				field = new LabelField(item.getCodigoSistema(),
						DrawStyle.ELLIPSIS);
				field.setFont(workflowFont);
				fields[0][2] = field;
				field = new LabelField(item.getTipoAutorizacion(),
						DrawStyle.ELLIPSIS);
				field.setFont(workflowFont);
				fields[0][3] = field;
				columnWidths = new int[] { unit + (unit / 2),
						unit + (unit / 2), unit + (unit / 2), unit * 6 };
				paddings = new int[] { 0, 0, 0, 0 };

			} else {
				fields[0][0] = new LabelField(String.valueOf(item.getTkiid()),
						DrawStyle.ELLIPSIS);
				fields[0][1] = new LabelField(item.getName(),
						DrawStyle.ELLIPSIS);
				fields[0][2] = new LabelField(item.getPriority(),
						DrawStyle.ELLIPSIS);
				fields[0][3] = new LabelField(item.getSubject(),
						DrawStyle.ELLIPSIS);
				columnWidths = new int[] { unit, unit * 2, unit * 2, unit * 5 };
				paddings = new int[] { 5, 0, 0, 0 };

			}
			tableListField = new TableListField(userData, fields, columnWidths,
					paddings) {
				protected boolean trackwheelClick(int status, int time) {
					int selectedIndex = this.getSelectedIndex();
					AutorizacionScreen autorizacionScreen = null;
					WorkItem item = (WorkItem) this.getUserData(selectedIndex);
					autorizacionScreen = new AutorizacionScreen(item);
					openScreen(autorizacionScreen);
					return true;
				}
			};
			vfm.add(tableListField);
		}
		return vfm;
		

	}

	protected void onExposed() {
		super.onExposed();
		resumePoll();
	}

	protected void onObscured() {
		super.onObscured();
		suspendPoll();
	}

	private void stopPoll() {
		if (pollThread != null)
			pollThread.stop();
	}
	
	private void suspendPoll() {
		if (pollThread != null)
			pollThread.suspend();
	}
	private void resumePoll() {
		if (pollThread != null)
			pollThread.resume();
	}

	public boolean onClose() {
		setDirty(false);
		stopPoll();
		tareas = null;
		manager = null;
		tableManager = null;
		return super.onClose();
	}

	/************** MENU ************************************/
	protected void makeMenu(Menu menu, int instance) {
		super.makeMenu(menu, instance);
		menu.add(new MenuItem(new StringProvider(WorklistMessages.getInstance()
				.getMessageForKey("menu.buscar.caso")), 0, 10000) {
			public void run() {
				openScreen(new WorklistSearchScreen());
			}
		});
		menu.add(MenuItem.separator(0));
	}

	/******************************************************/

	/************** HTTTP HELPER DELEGATE METHODS ************************************/
	public void onTimeout() {
		stopPoll();
		ApplicationPreferences.getInstance().logout();
	}

	public void didFailWithError(HttpError error) {
		stopPoll();
		if (error.getStatusCode() == HttpConnection.HTTP_UNAUTHORIZED) {
			ApplicationPreferences.getInstance().logout();
		}
	}

	public void didReceiveData(byte[] data) {

		AbstractParser objectParser = null;
		if (BpmServiceResources.getInstance().isCurrentEngineWorkflow()) {
			objectParser = new WorkItemParser();
		} else {
			objectParser = new TareaParser();
		}
		try {
			Vector tareasVector = objectParser.readList(new String(data,
					"UTF-8"));
			if (tareasVector != null) {
				tareas = new SimpleSortingVector();
				tareas.setSortComparator(new WorkItemComparator());
				for (int i = 0; i < tareasVector.size(); i++) {
					tareas.addElement(tareasVector.elementAt(i));
				}
				tareas.setSort(true);
				tareas.reSort();
			}
			tareasVector=null;
			layoutScreen();

		} catch (ParserException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
	}
	
	public void layoutScreen(){
		UiApplication.getUiApplication().invokeLater(new Runnable() {

			public void run() {
				int fieldCount = manager.getFieldCount();
				for (int i = 0; i < fieldCount; i++) {
					manager.delete(manager.getField(0));
				}
				System.out.println("STARTED CREATING LAYOUT "+new Date());
				tableManager = createTableLayout();
				System.out.println("STARTED ADDING LAYOUT "+new Date());
				manager.add(tableManager);
				System.out.println("FINISHED ADDING LAYOUT "+new Date());
			}
		});

	}

	/************************************************************************************/

	public SimpleSortingVector getTareas() {
		return tareas;
	}

}

 

package com.kruger.networking;

import java.util.Hashtable;

import javax.microedition.io.HttpConnection;

import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.ui.container.MainScreen;

import com.kruger.networking.interfaces.HttpDelegate;
import com.kruger.networking.interfaces.TimeoutDelegate;

import ec.com.smx.workflow.movil.ApplicationPreferences;
import ec.com.smx.workflow.movil.ErrorDialogManager;

/**
 * @author pochoa
 *	
 *	HttpHelper handles possible errors and timeouts of the request,
 *  also it sets the request headers common for all the request done 
 *  by the application.
 *  
 *  It executes error delegate messages on target objects
 */
public class HttpHelper extends Thread implements TimeoutDelegate {

	public static final int TIMEOUT_RESPONSE_CODE = 0;
	public static final int NO_METHOD_SPECIFIED_RESPOSE_CODE = -1;
	public static final int INTERNAL_ERROR_RESPONSE_CODE = -2;

	private Hashtable postData;
	private String url;
	private String operation;
	private HttpDelegate delegate;
	private MainScreen screen;
	private TimeOutThread timeout;
	private boolean appendDeviceId = false;

	

	/**
	 * @param url. Http Request URL
	 * @param postdata. Data to be sent inside the body of the request, only used when @param operation equals GET,
	 * if null an empty body will be sent
	 * @param delegate. Delegate that implements the @interface HttpDelegate and will be informed of http events 
	 * @param operation. Http Method to use
	 * @param screen. If screen is not null, the error dialog manager will try to dismiss this screen, it should be the current active screen
	 * @param appendDeviceId. If set true, the device PIN will be appended on HTTP Headers
	 */
	public HttpHelper(String url, Hashtable postdata, HttpDelegate delegate,
			String operation, MainScreen screen, boolean appendDeviceId) {
		this.url = url;
		this.postData = postdata;
		this.delegate = delegate;
		this.operation = operation;
		this.screen = screen;
		this.timeout = new TimeOutThread(this,
				ApplicationPreferences.getInstance().getNetworkTimeout());
		this.appendDeviceId = appendDeviceId;
	}

	public void throwErrorThread(final HttpError error) {
		Thread delegateThread = new Thread() {
			public void run() {
				delegate.didFailWithError(error);
			}
		};
		delegateThread.start();
	}

	public void throwTimeoutThread() {
		Thread delegateThread = new Thread() {
			public void run() {
				delegate.onTimeout();
			}
		};
		delegateThread.start();
	}

	/**
	 * @param responseCode
	 * 
	 *            Handle Error already stops the timeout Thread
	 */
	public void handleError(final int responseCode) {
		HttpError error;
		timeout.stop();
		switch (responseCode) {
		case TIMEOUT_RESPONSE_CODE: {
			ErrorDialogManager.showTimeoutDialog(screen);
			error = new HttpError(responseCode, "Timeout exceeded");
			throwTimeoutThread();
			return;
		}
		case INTERNAL_ERROR_RESPONSE_CODE: {
			ErrorDialogManager.showInternalErrorDialog(screen);
			error = new HttpError(responseCode, "Internal error");
			break;
		}
		case HttpConnection.HTTP_NOT_FOUND: {
			ErrorDialogManager.showResourceNotFoundDialog(screen);
			error = new HttpError(responseCode, "Http Resource not found");
			break;
		}
		case HttpConnection.HTTP_BAD_REQUEST:
		case HttpConnection.HTTP_BAD_METHOD: {
			ErrorDialogManager.showBadRequestMethodDialog(screen);
			error = new HttpError(responseCode, "Bad Request");
			break;
		}
		case HttpConnection.HTTP_UNAUTHORIZED: {
			ErrorDialogManager.showUnAuthorizedDeviceDialog(screen);
			error = new HttpError(responseCode, "Unauthorized Device");
			break;

		}
		case HttpConnection.HTTP_UNAVAILABLE:
		case HttpConnection.HTTP_BAD_GATEWAY:
		case HttpConnection.HTTP_GATEWAY_TIMEOUT:
		case HttpConnection.HTTP_INTERNAL_ERROR: {
			ErrorDialogManager.showServerErrorDialog(screen);
			error = new HttpError(responseCode, "Server Error");
			break;
		}

		default: {
			ErrorDialogManager.showServerErrorDialog(screen);
			error = new HttpError(HttpConnection.HTTP_INTERNAL_ERROR,
					"Server Error");
			break;
		}
		}
		throwErrorThread(error);
	}

	
	public void run() {
		if (operation == null) {
			handleError(NO_METHOD_SPECIFIED_RESPOSE_CODE);
			return;
		}
		timeout.start();
		Hashtable requestProperties=new Hashtable();
		
		/* Code for Basic Authentication */
		// connection.setRequestProperty("Authorization", "Basic "// +
		// encodedLogin);
		if (appendDeviceId == true) {
				// Send the Device PIN number
			requestProperties.put("DeviceId", Integer.toHexString( DeviceInfo.getDeviceId()));
		}
		if(ApplicationPreferences.getInstance().getSessionCookieHeader()!=null){
			requestProperties.put(ApplicationPreferences.sessionCookieHeaderName, ApplicationPreferences.getInstance().getSessionCookieHeader());
		}
		if(ApplicationPreferences.getInstance().getCookies()!=null){
			requestProperties.put("Cookie", ApplicationPreferences.getInstance().getCookies());
		}
		HttpRequest request;
		if (operation == HttpConnection.GET) {
			request = new HttpGet(this, url,requestProperties);
		} else if (operation == HttpConnection.POST) {
			request = new HttpPost(this, url, requestProperties,postData);
		} else{
			return;
		}
		request.executeRequest();
	}

	public TimeOutThread getTimeout() {
		return timeout;
	}

	public HttpDelegate getDelegate() {
		return delegate;
	}

	public void onTimeout() {
		timeout.stop();
		handleError(TIMEOUT_RESPONSE_CODE);

	}

}

 

package com.kruger.networking;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;

import javax.microedition.io.HttpConnection;

import net.rim.device.api.io.IOUtilities;

public class HttpGet extends HttpRequest {

	public HttpGet(HttpHelper helper,String uri,Hashtable properties)
	{
				super(helper, uri,properties);
	}

	public void executeRequest() {
		
		DataInputStream din = null;
		System.out.println("NETWORKING CODE STARTED AT: "+new Date());
		int responseCode;
		// RequestUtil.printHeaders(connection);
		final byte[] responseBytes;
		try {
			responseCode = getConnection().getResponseCode();
			if(helper.getTimeout().getStatus()==true) return;
			
			switch (responseCode) {
				case HttpConnection.HTTP_OK: {
					din = getConnection().openDataInputStream();
					responseBytes=IOUtilities.streamToBytes(din);
					break;
				}
				default: {
					helper.handleError(responseCode);
					return;
				}
				
			}
			System.out.println("BYTES FINALLY RECEIVED AT: "+new Date());
			if (responseBytes != null && responseCode != 0) {
				Thread delegateThread = new Thread() {
					public void run() {
						helper.getDelegate().didReceiveData(responseBytes);
					}
				};
				helper.getTimeout().stop();
				delegateThread.start();
				return;
			}

		} catch (IOException e) {
			helper.handleError(HttpHelper.TIMEOUT_RESPONSE_CODE);
			e.printStackTrace();
			return;
		} finally {
			try {
				din.close();
				din=null;
				getConnection().close();
				connection=null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public String getRequestMethod() {
		return HttpConnection.GET;
	}

	protected Hashtable appendAdditionalProperties(Hashtable requestProperties) {
		return requestProperties;
	}
	
	
	
}

 Thanks.

Developer
maadani
Posts: 729
Registered: ‎05-04-2011
My Device: 9700

Re: Serious networking problems on app

 

hi @

 

I suggest you would add some logging calls with the current time, Syste.currentTimeInMillis, so you would have better idea what's causing the latency.

 

E.

Regular Contributor
pablo_ivan57
Posts: 60
Registered: ‎02-24-2011
My Device: Not Specified

Re: Serious networking problems on app

[ Edited ]

Ok, Tried as you suggested, here is the output on the debug console

 

[0.0] VM:ACGRt=1,c=0
[0.0] NETWORKING CODE STARTED AT: Tue Jun 05 14:15:53 America/Bogota 2012
[0.0] TAC:TAI.handleRegRsp : ALREADY_REGISTERED
[0.0] TAC:TAI.handleRegRsp : (ALREADY_REGISTERED), pending entry copying
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] JVM: bklt @354591328: timer
[0.0] JVM: bklt[1] @354591328: usrIdle 11, usrTime 30, usrAct 1
[0.0] JVM: bklt[1] @354591328: chkIdle 29, currTime 30
[0.0] JVM: bklt @354591328: setTimer 19
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] JVM: bklt @354610250: timer
[0.0] JVM: bklt[1] @354610250: usrIdle 30, usrTime 30, usrAct 1
[0.0] JVM: bklt[1] @354610250: chkIdle 48, currTime 30
[0.0] JVM: bklt[1] @354610250: enableBacklight 0
[0.0] JVM: bklt[1]: setTimeout 30
[0.0] BYTES FINALLY RECEIVED AT: Tue Jun 05 14:16:24 America/Bogota 2012
[0.0] DID RECEIVE DATA AT: Tue Jun 05 14:16:24 America/Bogota 2012

 

And the second try

 

[0.0] Signal level only changed - ONS not updated
[0.0] JVM: bklt[1] @354781156: JBSC on=1
[0.0] JVM: bklt[1] @354781156: SC 1
[0.0] JVM: bklt @354781156: setTimer 30
[0.0] NETWORKING CODE STARTED AT: Tue Jun 05 14:19:16 America/Bogota 2012
[0.0] TAC:TAI.handleRegRsp : ALREADY_REGISTERED
[0.0] TAC:TAI.handleRegRsp : (ALREADY_REGISTERED), pending entry copying
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] BYTES FINALLY RECEIVED AT: Tue Jun 05 14:19:33 America/Bogota 2012
[0.0] DID RECEIVE DATA AT: Tue Jun 05 14:19:33 America/Bogota 2012

Third try:

 

[0.0] NETWORKING CODE STARTED AT: Tue Jun 05 14:22:34 America/Bogota 2012
[0.0] TAC:TAI.handleRegRsp : ALREADY_REGISTERED
[0.0] TAC:TAI.handleRegRsp : (ALREADY_REGISTERED), pending entry copying
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] Signal level only changed - ONS not updated
[0.0] BYTES FINALLY RECEIVED AT: Tue Jun 05 14:22:51 America/Bogota 2012
[0.0] DID RECEIVE DATA AT: Tue Jun 05 14:22:52 America/Bogota 2012

 

 

 I commented all of the parsing and drawing code on the device, this is the output of just the networking code. (Opening a connection and downloading the 20k file). However the problem is the same,  as you can see there is a lot of variability. The last thing that I can think of is a problem with the proxy settings in the network. However there's no way to specify an HTTP proxy on the Curve's OS 6 and even on code, HTTPConnection has no way to specify that.  Any other suggestion that you could have??? I am desperate trying to resolve these issues...

 

At first it would seem like a memory leak on the networking code (HTTPGet class...), cause by doing 3 o 4 times the same operation the time took to download everything incresases to 1 min, however there's no clear pattern, sometimes there are 4 o 5 times in a row where data is retrieved innmediately, less than 5 secs... but on the other hand sometimes it takes 1 minute to 1 and 30 minutes to do it.  For example 3 tests: All of them take between half to 1 minute, and then the test number 4 just takes 5 to 10 seconds... I don't know what's going on...

 

On thing to note, the same call to the same server on an iPhone 4 takes 1 sec to retrieve all the data from it, obviously the iPhone asked for http authentication on the server proxy domain. But still it's an incredible difference, 1 sec vs 10 sec that's taking the Blackberry Curve.  What I'm starting to be sure is that there aren't any problems on the code that would be the cause of the issue.

 

Thanks a lot.

 

Developer
maadani
Posts: 729
Registered: ‎05-04-2011
My Device: 9700

Re: Serious networking problems on app

Let's eliminate the proxy issue.

 

Disable the wifi on your device and run your application again.

 

Also, I haven't seen the code which handle the transport selection.

 

Can you please show us how you handle this issue?

 

E.

Regular Contributor
pablo_ivan57
Posts: 60
Registered: ‎02-24-2011
My Device: Not Specified

Re: Serious networking problems on app

Mmmm you're right, forgot the base class, here it is...

 

package com.kruger.networking;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.microedition.io.HttpConnection;

import net.rim.device.api.io.transport.ConnectionDescriptor;
import net.rim.device.api.io.transport.ConnectionFactory;

public abstract class HttpRequest {

	protected HttpHelper helper;
	protected String uri;
	protected Hashtable requestProperties;
	
	private ConnectionFactory connectionFactory = new ConnectionFactory();
	protected HttpConnection connection;
	
	public HttpRequest(HttpHelper helper,String url,Hashtable requestProperties){
		this.helper=helper;
		this.uri=url;
		this.requestProperties=requestProperties;
	}
	
	private HttpConnection createConnection(){
		this.requestProperties=appendAdditionalProperties(requestProperties);
		ConnectionDescriptor connectionDescriptor = connectionFactory
				.getConnection(uri);
		HttpConnection connection = (HttpConnection) connectionDescriptor
				.getConnection();
		try {
			connection.setRequestMethod(getRequestMethod());
			Enumeration requestKeys=requestProperties.keys();
			while (requestKeys.hasMoreElements()) {
				Object key = (Object) requestKeys.nextElement();
				Object value = requestProperties.get(key);
				connection.setRequestProperty(key.toString(), value.toString());
			}
			
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		
		return connection;
	}
	
	protected HttpConnection getConnection(){
		if(connection==null){
			connection=createConnection();
		}
		return connection;
	}
	
	
	protected abstract String getRequestMethod();
	
	protected abstract Hashtable appendAdditionalProperties(Hashtable requestProperties);
			
	public abstract void executeRequest();
}

 By disabling the wifi on the device, the application won't be able to reach the server... a timeout message would appear in that case (As expected).

Developer
peter_strange
Posts: 19,610
Registered: ‎07-14-2008
My Device: Not Specified

Re: Serious networking problems on app

[ Edited ]

Good thought maadani.

 

If you know you are using WiFi, then you are probably causing overhead with ConnectionFactory.  As I understand it, ConnectionFactory will attempt to find a suitable connection and may waste time checking things that don't actually work. 

 

If you only allow WiFi, then  you can slap ";interface=wifi" on your URL and just open your own HttpConnection. 

 

Alternatively just tell ConnectionFactory to only use WiFi.  To do this:

 

before:

  ConnectionDescriptor connectionDescriptor = connectionFactory
.getConnection(uri);

 

add something like:

 

        int[] disallowedTransportTypes = { TransportInfo.TRANSPORT_MDS, TransportInfo.TRANSPORT_TCP_WIFI, TransportInfo.TRANSPORT_BIS_B, TransportInfo.TRANSPORT_TCP_CELLULAR, TransportInfo.TRANSPORT_WAP2, TransportInfo.TRANSPORT_WAP };
        int[] preferredTransportTypes = { TransportInfo.TRANSPORT_TCP_WIFI };

then...

       connectionFactory.setPreferredTransportTypes(preferredTransportTypes);
       connectionFactory.setDisallowedTransportTypes(disallowedTransportTypes);

Regular Contributor
pablo_ivan57
Posts: 60
Registered: ‎02-24-2011
My Device: Not Specified

Re: Serious networking problems on app

[ Edited ]

Thanks for the suggestion, I tried it by adding ;deviceside=true;interface=wifi; to the URI param and creating my own httpConnection, but it made little or no difference, still the same problem, the lag is produced at this point:

 

responseCode = getConnection().getResponseCode();
			if(helper.getTimeout().getStatus()==true) return;
			
			switch (responseCode) {
				case HttpConnection.HTTP_OK: {
					din = getConnection().openDataInputStream();
					responseBytes=IOUtilities.streamToBytes(din);
					break;
				}
				default: {
					helper.handleError(responseCode);
					return;
				}
				
			}
			System.out.println("BYTES FINALLY RECEIVED AT: "+new Date());

Could it really be that the Curve is so slow handling networking code?? Cause there's nothing left... except for the proxy issue ( Maybe it's lagging trying to detect the correct address or collision issues?) , I ran out of ideas...

Thank you so much for you answers.

Developer
shism2
Posts: 246
Registered: ‎12-13-2010
My Device: Not Specified

Re: Serious networking problems on app

responseBytes=IOUtilities.streamToBytes(din);

 If your only using wifi, how about reading in larger chunks of data at a time? I think the above code reads 1024 bytes at a time.

Developer
peter_strange
Posts: 19,610
Registered: ‎07-14-2008
My Device: Not Specified

Re: Serious networking problems on app

AFAIK, the streamTobyte is as fast as it can get.

 

I can't find createConnection() in the code supplied.  If you are using wifi directly, then do you still call this?

 

However I am wondering if we need to look at a specific device issue here.  Sorry I can't remember if you have said you have tried this on a number of BlackBerry devices.  I think in a previous Thread you said you had.  Can you remind us what devices and what OS levels?

 

Cheers

Regular Contributor
pablo_ivan57
Posts: 60
Registered: ‎02-24-2011
My Device: Not Specified

Re: Serious networking problems on app

Ok, createConnection is on the HttpRequest class, It's on the 3rd or 4th post, I will improve it with the wifi connection parameters you told on subsequent posts, and yes I still call that function. About the device... haven't tried the application on other ones, besides the Curve 9300.

I also have a Storm 9550, however it doesn't have BB OS 6 yet... (Activity View breaks the compilation in that case), and unfortunately I can't try my app on it. The OS level for the BB Curve is 6.0 Bundle 2949