برنامه نویسی رو با هم یاد می‌گیریم



چگونه می‌توان کد کاتلین را به جاوا تبدیل کرد؟

در IntelliJ یا Android Studio، برای تبدیل کد kotlin به جاوا، کافی است کارهای زیر را انجام دهید:

  1. Menu > Tools > Kotlin > Show Kotlin Bytecode
  2. بر روی  Decompile کلیک کنید.
  3.  فایل جاوا را کپی کنید.

در نسخه‌های 1.2 به بعد افزونه Kotlin، می توانید مستقیماً از مسیر زیر استفاده کنید.

Menu > Tools > Kotlin -> Decompile Kotlin to Java.


برای lazy load کردن تصاویر در listview روش های متفاوتی وجود دارد، در ادامه به آموزش دو روش آن می‌پردازیم.

روش اول

این کد برای نگه داشتن تصاویری که برنامه در حال نمایش است نوشته شده است. توجه داشته باشید که شیء "Log" مورد استفاده در اینجا custom wrapper در کلاس Log نهایی در اندروید است.

package com.wilson.android.library;

/*
 Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/
import java.io.IOException;

public class DrawableManager {
    private final Map<String, Drawable> drawableMap;

    public DrawableManager() {
        drawableMap = new HashMap<String, Drawable>();
    }

    public Drawable fetchDrawable(String urlString) {
        if (drawableMap.containsKey(urlString)) {
            return drawableMap.get(urlString);
        }

        Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src");


            if (drawable != null) {
                drawableMap.put(urlString, drawable);
                Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                        + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                        + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
            } else {
              Log.w(this.getClass().getSimpleName(), "could not get thumbnail");
            }

            return drawable;
        } catch (MalformedURLException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        } catch (IOException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        }
    }

    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
        if (drawableMap.containsKey(urlString)) {
            imageView.setImageDrawable(drawableMap.get(urlString));
        }

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                imageView.setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                //TODO : set imageView to a "pending" image
                Drawable drawable = fetchDrawable(urlString);
                Message message = handler.obtainMessage(1, drawable);
                handler.sendMessage(message);
            }
        };
        thread.start();
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(urlString);
        HttpResponse response = httpClient.execute(request);
        return response.getEntity().getContent();
    }
}

روش دوم:

LazyList چیست؟

LazyList یک کتابخانه ساده برای نمایش تصاویر در Android ListView است.

نحوه استفاده:

ImageLoader imageLoader=new ImageLoader(context);
.
imageLoader.DisplayImage(url, imageView);

فراموش نکنید که مجوزهای زیر را به AndroidManifest.xml خود اضافه کنید:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

تنها یک نمونه از ImageLoader ایجاد کنید و از آن در سراسر برنامه خود استفاده کنید. به این ترتیب کش کردن تصاویر بسیار کارآمدتر خواهد بود.

نحوه عملکرد این روش:

در این روش تصاویر در thread پس زمینه دانلود می‌شود. تصاویر روی کارت SD و در حافظه کش ذخیره می شوند. اجرای کش بسیار ساده است و فقط برای نسخه ی demo کافی است. من تصاویر را با inSampleSize رمزگشایی می کنم تا استفاده از memory را کاهش دهم.


برای انتقال داده ها بین Activities در برنامه اندروید باید session id برای activityها در دسترس باشد.

چگونه می‌توان session id را برای همه activityها در دسترس نگه داشت؟

روش اول:

در فعالیت فعلی خود، یک Intent جدید ایجاد کنید:

String value="Hello world";
Intent i = new Intent(CurrentActivity.this, NewActivity.class);    
i.putExtra("key",value);
startActivity(i);

 

سپس در Activity جدید، این مقادیر را بازیابی کنید:

Bundle extras = getIntent().getExtras();
if (extras != null) {
    String value = extras.getString("key");
    //The key argument here must match that used in the other activity
}

 

از این تکنیک برای انتقال متغیرها از یک Activity به دیگری استفاده کنید.

روش دوم:

همچنین می‌توانید از روش زیز استفاده کنید.

ساده ترین راه برای انجام این کار این است که session id را به signout در Intent که برای شروع Activity استفاده می کنید، ارسال کنید:

Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("EXTRA_SESSION_ID", sessionId);
startActivity(intent);

 

و در Activity بعدی به آن intent دسترسی داشته باشید:

String sessionId = getIntent().getStringExtra("EXTRA_SESSION_ID");

 


چگونه یک دستگاه اندرویدی را به لرزش درآوریم؟

در این مقاله می‌خواهیم نحوه به ارزش درآوردن گوشی اندروید با برنامه نویسی اندروید را آموزش دهیم.

1-اجازه ویبره را به اپلیکشین دهید

قبل از شروع اجرای هر کد ارتعاشی، باید به برنامه خود اجازه ارتعاش بدهید:

<uses-permission android:name="android.permission.VIBRATE"/>

 

مطمئن شودی که این کد را در فایل AndroidManifest.xml خود قرار دهید.

2- کتابخانه Vibration را وارد کنید

بیشتر IDE ها این کار را می‌کنند اما اگر احیانا IDE شما این کار را انجام نداد 

 import android.os.Vibrator;



را اضافه کنید.

مطمئن شوید که کد را در قسمتی که می‌خواهید لرزش در آن رخ دهد، قرار دهید.

3- چگونه می‌توان ویبره را در زمان مشخصی انجام داد

در بیشتر مواقع، می خواهید دستگاه را برای مدت زمان کوتاه و از پیش تعیین شده ای ویبره کنید. شما می توانید با استفاده از روش vibrate(long milliseconds) به این هدف برسید.به مثال زیر توجه کنید:

// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

// Vibrate for 400 milliseconds
v.vibrate(400);

 

4- چگونه زمان وییزه را بی نهایت کنیم

ممکن است بخواهید دستگاه به طور نامحدود به لرزش ادامه دهد. برای این کار از روش vibrate(long[] pattern, int repeat) استفاده می کنیم:

// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

// Start without a delay
// Vibrate for 100 milliseconds
// Sleep for 1000 milliseconds
long[] pattern = {0, 100, 1000};

// The '0' here means to repeat indefinitely
// '0' is actually the index at which the pattern keeps repeating from (the start)
// To repeat the pattern from any other point, you could increase the index, e.g. '1'
v.vibrate(pattern, 0);

 

و هنگامی که می‌خواهید لرزش متوقف شود،cancel()را فراخوانی کنید:

v.cancel();

5- ویبره به صورت الگوهای تکرار شونده

اگر می‌خواهید لرزش با سلیقه خود داشته باشید، می‌توانید الگوهای ارتعاشی خود را ایجاد کنید:

// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

// Start without a delay
// Each element then alternates between vibrate, sleep, vibrate, sleep.
long[] pattern = {0, 100, 1000, 300, 200, 100, 500, 200, 100};

// The '-1' here means to vibrate once, as '-1' is out of bounds in the pattern array
v.vibrate(pattern, -1);

 

عیب‌یابی

اگر با اعمال کدها دستگاه شما به لرزش درنمی‌آید، ابتدا مطمئن شوید گوشی شما چنین قابلیتی دارد:

// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

// Output yes if can vibrate, no otherwise
if (v.hasVibrator()) {
    Log.v("Can Vibrate", "YES");
} else {
    Log.v("Can Vibrate", "NO");
}

 

سپس مطمئن شوید که به اپلیکیشن خود اجازه ویبره را داده اید. (مرحله 1)

<uses-permission android:name="android.permission.VIBRATE"/>

 


stack trace چیست؟

stack trace فهرستی از فراخوانی‌های متد است که وقتی Exception رخ داده، اپلیکیشن در وسط آن بوده.

این بسیار مفید است زیرا نه تنها به شما نشان می دهد که خطا کجا رخ داده است، بلکه نحوه پایان برنامه در آن مکان کد را نیز نشان می دهد. این منجر به سوال بعدی می شود:

 

مثال ساده‌ای از stack trace

با مثالی که در سوال داده شد، می‌توانیم دقیقاً مشخص کنیم که این استثنا در کجای برنامه رخ داده است. بیایید نگاهی به stack trace بیندازیم:

 

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

 

این یک stack trace بسیار ساده است. اگر از ابتدای لیست "at ." شروع کنیم، می توانیم بگوییم که خطای ما کجا رخ داده است. آنچه ما به دنبالش هستیم بالاترین فراخوانی متد» است که بخشی از برنامه ما است. در این مورد:

 

at com.example.myproject.Book.getTitle(Book.java:16)

 

برای رفع این ارور، می‌توانیم Book.java را باز کرده و به خط 16 نگاه کنیم که عبارت است از:

 

15   public String getTitle() {
16      System.out.println(title.toString());
17      return title;
   }

 

این نشان می دهد که چیزی (احتمالا عنوان) در کد بالا تهی است.

 

آموزش نحوه دیباگ کردن اپلیکیشن با آنالیز کردن stack trace

گاهی اوقات برنامه‌ها یک Exception را می‌گیرند و دوباره آن را به‌عنوان علت یک exception دیگر نشان می‌دهند. که به طور معمول اینگونه به نظر می رسد:

 

34   public void getBookIds(int id) {
35      try {
36         book.getId(id);    // this method it throws a NullPointerException on line 22
37      } catch (NullPointerException e) {
38         throw new IllegalStateException("A book has a null property", e)
39      }
40   }

 

که ممکن است به شما یک stack trace شبیه مثال زیر دهد:

 

Exception in thread "main" java.lang.IllegalStateException: A book has a null property
        at com.example.myproject.Author.getBookIds(Author.java:38)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
Caused by: java.lang.NullPointerException
        at com.example.myproject.Book.getId(Book.java:22)
        at com.example.myproject.Author.getBookIds(Author.java:36)
        . 1 more

 

چیزی که در مورد این مورد متفاوت است "Caused by" است. گاهی اوقات Exception  ها دارای چندین بخش "Caused by" هستند. برای این موارد، شما معمولاً می خواهید علت اصلی» (root cause) را پیدا کنید، که یکی از پایین ترین بخش های Caused by» در ردیابی stack trace خواهد بود. که در این مورد:

 

Caused by: java.lang.NullPointerException <-- root cause
        at com.example.myproject.Book.getId(Book.java:22) <-- important line

 

، با این Exception، می خواهیم به خط 22 Book.java نگاه کنیم تا ببینیم چه چیزی ممکن است باعث NullPointerException شود.

 

آنالیز و رفع ارور با استفاده از کد کتابخانه

معمولا stack traceها بسیار پیچیده تر از دو مثال بالا هستند. در اینجا یک مثال آورده شده است (مثالی طولانی که چندین سطح از استثناهای زنجیره ای را نشان می دهد):

 

javax.servlet.ServletException: Something bad happened
    at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.example.myproject.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.example.myproject.OutputBufferFilter.doFilter(OutputBufferFilter.java:33)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:2)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:4)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:2)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: com.example.myproject.MyProjectServletException
    at com.example.myproject.MyServlet.doPost(MyServlet.java:169)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:30)
    . 27 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.example.myproject.MyEntity]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:64)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2329)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2822)
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:705)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:693)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:689)
    at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344)
    at $Proxy19.save(Unknown Source)
    at com.example.myproject.MyEntityService.save(MyEntityService.java:59) <-- relevant call (see notes below)
    at com.example.myproject.MyServlet.doPost(MyServlet.java:164)
    . 32 more
Caused by: java.sql.SQLException: Violation of unique constraint MY_ENTITY_UK_1: duplicate value(s) for column(s) MY_COLUMN in statement [.]
    at org.hsqldb.jdbc.Util.throwError(Unknown Source)
    at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:57)
    . 54 more

 

در این مثال، موارد بسیار بیشتری وجود دارد. چیزی که ما بیشتر نگران آن هستیم این است که به دنبال methodهایی باشیم که از کد ما هستند، که می تواند هر چیزی در com.example.myproject باشد.

از مثال دوم (بالا)، ابتدا می‌خواهیم علت اصلی آن را بررسی کنیم:

Caused by: java.sql.SQLException

 

به هر حال، همه فراخوانی‌های متد تحت آن کد کتابخانه هستند. بنابراین ما به سمت "Caused by" بالای آن حرکت می کنیم و در بلوک "Caused by" به دنبال اولین فراخوانی متد نشأت گرفته از کد ما باشید که عبارت است از:

at com.example.myproject.MyEntityService.save(MyEntityService.java:59)

 

مانند نمونه‌های قبلی، ما باید به MyEntityService.java در خط 59 نگاه کنیم، زیرا این خطا از آنجا نشأت گرفته است (در این مثال هم کمی واضح است که چه اشتباهی رخ داده است، زیرا SQLException خطا را بیان می‌کند، اما روش اشکال‌زدایی همان چیزی است که ما دنبال می‌کنیم).


سوالات زیادی وجود دارد مبنی بر اینکه برنامه آنها از کار افتاده است. هدف این سوال آموزش برنامه نویسان مبتدی اندروید است که چگونه سعی کنند مشکلات خود را خودشان برطرف کنند یا سوالات درست را بپرسند.

 

دلیل این ارور چیست؟

برنامه شما بخاطر RuntimeException پیش بینی نشده از کار افتاده است. و در بیشتر اوقات بخاطر NullPointerException است.

 

چگونه می‌توان ارور Unfortunately MyApp has stopped» را رفع کرد؟

هر بار که یک اپلیکیشن اندروید هنگ می‌کند، یک Stack Trace روی کنسول نوشته می شود (در این مورد، logcat). این Stack Trace حاوی اطلاعات حیاتی برای حل مشکل شما است.

 

1- پیدا کردن stack trace در Android Studio

در نوار پایین پنجره، روی دکمه Logcat کلیک کنید. همچنین می توانید alt+6 را فشار دهید. مطمئن شوید که شبیه ساز یا دستگاه شما در پانل Devices انتخاب شده است. در مرحله بعد سعی کنید stack trace را پیدا کنید که با رنگ قرمز نشان داده شده است. ممکن است موارد زیادی به logcat وارد شده باشد، بنابراین شاید لازم باشد کمی اسکرول کنید. یک راه آسان برای یافتن stack trace این است که logcat را پاک کنید (با استفاده از سطل بازیافت سمت راست)، و اجازه دهید برنامه دوباره هنگ کند.

 

رفع ارور Unfortunately, MyApp has stopped.

 

2- دیباگ کردن اپلیکیشن با Stack Trace

پیدا کردن مشکل نیمی از موفقیت است. در این مرحله باید با تجزیه و تحلیل stack trace دریابید که دقیقا چه چیزی باعث خرابی اپلیکیشن شما شده است.

 

مشکل برطرف نشده؟

اگر Exception و خطی را که در آن رخ داده است پیدا کرده‌اید و هنوز نمی‌توانید نحوه رفع آن را بیابید، در StackOverflow سوال  خود ر مطرح کنید.

سعی کنید تا حد امکان مختصر باشید: stack trace و کد مربوطه را از چند خط قبل‌تر از Exception ارسال کنید.


آخرین ارسال ها

آخرین جستجو ها


bestcctvv تولیدات آلومینیومی و فویل آلومینیومی مجله سرگرمی وبلاگ تخصصی برنامه نویسی و سئو هادی ندائی مطالب اینترنتی دیده بان استارت اپ storekala مطالب اینترنتی Virginia's memory